mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:37:32 +00:00
feat(API): support V2 token and session token usage (#6180)
This PR adds support for userinfo and introspection of V2 tokens. Further V2 access tokens and session tokens can be used for authentication on the ZITADEL API (like the current access tokens).
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
openid "github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||
"github.com/zitadel/zitadel/internal/repository/idp"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/auth"
|
||||
mgmt "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha"
|
||||
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha"
|
||||
@@ -29,6 +30,7 @@ type Client struct {
|
||||
CC *grpc.ClientConn
|
||||
Admin admin.AdminServiceClient
|
||||
Mgmt mgmt.ManagementServiceClient
|
||||
Auth auth.AuthServiceClient
|
||||
UserV2 user.UserServiceClient
|
||||
SessionV2 session.SessionServiceClient
|
||||
OIDCv2 oidc_pb.OIDCServiceClient
|
||||
@@ -40,6 +42,7 @@ func newClient(cc *grpc.ClientConn) Client {
|
||||
CC: cc,
|
||||
Admin: admin.NewAdminServiceClient(cc),
|
||||
Mgmt: mgmt.NewManagementServiceClient(cc),
|
||||
Auth: auth.NewAuthServiceClient(cc),
|
||||
UserV2: user.NewUserServiceClient(cc),
|
||||
SessionV2: session.NewSessionServiceClient(cc),
|
||||
OIDCv2: oidc_pb.NewOIDCServiceClient(cc),
|
||||
@@ -134,6 +137,14 @@ func (s *Tester) RegisterUserPasskey(ctx context.Context, userID string) {
|
||||
logging.OnError(err).Fatal("create user passkey")
|
||||
}
|
||||
|
||||
func (s *Tester) SetUserPassword(ctx context.Context, userID, password string) {
|
||||
_, err := s.Client.UserV2.SetPassword(ctx, &user.SetPasswordRequest{
|
||||
UserId: userID,
|
||||
NewPassword: &user.Password{Password: password},
|
||||
})
|
||||
logging.OnError(err).Fatal("set user password")
|
||||
}
|
||||
|
||||
func (s *Tester) AddGenericOAuthProvider(t *testing.T) string {
|
||||
ctx := authz.WithInstance(context.Background(), s.Instance)
|
||||
id, _, err := s.Commands.AddOrgGenericOAuthProvider(ctx, s.Organisation.ID, command.GenericOAuthProvider{
|
||||
@@ -219,3 +230,20 @@ func (s *Tester) CreatePasskeySession(t *testing.T, ctx context.Context, userID
|
||||
return createResp.GetSessionId(), updateResp.GetSessionToken(),
|
||||
createResp.GetDetails().GetChangeDate().AsTime(), updateResp.GetDetails().GetChangeDate().AsTime()
|
||||
}
|
||||
|
||||
func (s *Tester) CreatePasswordSession(t *testing.T, ctx context.Context, userID, password string) (id, token string, start, change time.Time) {
|
||||
createResp, err := s.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
User: &session.CheckUser{
|
||||
Search: &session.CheckUser_UserId{UserId: userID},
|
||||
},
|
||||
Password: &session.CheckPassword{
|
||||
Password: password,
|
||||
},
|
||||
},
|
||||
Domain: s.Config.ExternalDomain,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return createResp.GetSessionId(), createResp.GetSessionToken(),
|
||||
createResp.GetDetails().GetChangeDate().AsTime(), createResp.GetDetails().GetChangeDate().AsTime()
|
||||
}
|
||||
|
@@ -64,6 +64,7 @@ const (
|
||||
|
||||
const (
|
||||
FirstInstanceUsersKey = "first"
|
||||
UserPassword = "VeryS3cret!"
|
||||
)
|
||||
|
||||
// User information with a Personal Access Token.
|
||||
|
@@ -8,25 +8,20 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/oidc/v2/pkg/client"
|
||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
||||
"github.com/zitadel/oidc/v2/pkg/client/rs"
|
||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||
|
||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||
oidc_internal "github.com/zitadel/zitadel/internal/api/oidc"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/app"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
func (s *Tester) CreateOIDCNativeClient(ctx context.Context, redirectURI string) (*management.AddOIDCAppResponse, error) {
|
||||
project, err := s.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{
|
||||
Name: fmt.Sprintf("project-%d", time.Now().UnixNano()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func (s *Tester) CreateOIDCNativeClient(ctx context.Context, redirectURI, projectID string) (*management.AddOIDCAppResponse, error) {
|
||||
return s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{
|
||||
ProjectId: project.GetId(),
|
||||
ProjectId: projectID,
|
||||
Name: fmt.Sprintf("app-%d", time.Now().UnixNano()),
|
||||
RedirectUris: []string{redirectURI},
|
||||
ResponseTypes: []app.OIDCResponseType{app.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
||||
@@ -74,6 +69,20 @@ func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI s
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Tester) CreateProject(ctx context.Context) (*management.AddProjectResponse, error) {
|
||||
return s.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{
|
||||
Name: fmt.Sprintf("project-%d", time.Now().UnixNano()),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Tester) CreateAPIClient(ctx context.Context, projectID string) (*management.AddAPIAppResponse, error) {
|
||||
return s.Client.Mgmt.AddAPIApp(ctx, &management.AddAPIAppRequest{
|
||||
ProjectId: projectID,
|
||||
Name: fmt.Sprintf("api-%d", time.Now().UnixNano()),
|
||||
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Tester) CreateOIDCAuthRequest(clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) {
|
||||
provider, err := s.CreateRelyingParty(clientID, redirectURI, scope...)
|
||||
if err != nil {
|
||||
@@ -123,12 +132,23 @@ func (s *Tester) CreateOIDCAuthRequestImplicit(clientID, loginClient, redirectUR
|
||||
return strings.TrimPrefix(loc.String(), prefixWithHost), nil
|
||||
}
|
||||
|
||||
func (s *Tester) OIDCIssuer() string {
|
||||
return http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure)
|
||||
}
|
||||
|
||||
func (s *Tester) CreateRelyingParty(clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) {
|
||||
issuer := http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure)
|
||||
if len(scope) == 0 {
|
||||
scope = []string{oidc.ScopeOpenID}
|
||||
}
|
||||
return rp.NewRelyingPartyOIDC(issuer, clientID, "", redirectURI, scope)
|
||||
return rp.NewRelyingPartyOIDC(s.OIDCIssuer(), clientID, "", redirectURI, scope)
|
||||
}
|
||||
|
||||
func (s *Tester) CreateResourceServer(keyFileData []byte) (rs.ResourceServer, error) {
|
||||
keyFile, err := client.ConfigFromKeyFileData(keyFileData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rs.NewResourceServerJWTProfile(s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key))
|
||||
}
|
||||
|
||||
func CheckRedirect(url string, headers map[string]string) (*url.URL, error) {
|
||||
@@ -153,11 +173,3 @@ func CheckRedirect(url string, headers map[string]string) (*url.URL, error) {
|
||||
|
||||
return resp.Location()
|
||||
}
|
||||
|
||||
func (s *Tester) CreateSession(ctx context.Context, userID string) (string, string, error) {
|
||||
session, err := s.Commands.CreateSession(ctx, []command.SessionCommand{command.CheckUser(userID)}, "domain.tld", nil)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return session.ID, session.NewToken, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user