mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:57:33 +00:00
feat: jwt as idp (#2363)
* feat: jwt idp * feat: command side * feat: add tests * fill idp views with jwt idps and return apis * add jwtEndpoint to jwt idp * begin jwt request handling * merge * handle jwt idp * cleanup * fixes * autoregister * get token from specific header name * error handling * fix texts * handle renderExternalNotFoundOption Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
@@ -42,6 +42,21 @@ func (s *Server) AddOIDCIDP(ctx context.Context, req *admin_pb.AddOIDCIDPRequest
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddJWTIDP(ctx context.Context, req *admin_pb.AddJWTIDPRequest) (*admin_pb.AddJWTIDPResponse, error) {
|
||||
config, err := s.command.AddDefaultIDPConfig(ctx, addJWTIDPRequestToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.AddJWTIDPResponse{
|
||||
IdpId: config.IDPConfigID,
|
||||
Details: object_pb.AddToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateIDP(ctx context.Context, req *admin_pb.UpdateIDPRequest) (*admin_pb.UpdateIDPResponse, error) {
|
||||
config, err := s.command.ChangeDefaultIDPConfig(ctx, updateIDPToDomain(req))
|
||||
if err != nil {
|
||||
@@ -101,3 +116,17 @@ func (s *Server) UpdateIDPOIDCConfig(ctx context.Context, req *admin_pb.UpdateID
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateIDPJWTConfig(ctx context.Context, req *admin_pb.UpdateIDPJWTConfigRequest) (*admin_pb.UpdateIDPJWTConfigResponse, error) {
|
||||
config, err := s.command.ChangeDefaultIDPJWTConfig(ctx, updateJWTConfigToDomain(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.UpdateIDPJWTConfigResponse{
|
||||
Details: object_pb.ChangeToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -31,6 +31,25 @@ func addOIDCIDPRequestToDomainOIDCIDPConfig(req *admin_pb.AddOIDCIDPRequest) *do
|
||||
}
|
||||
}
|
||||
|
||||
func addJWTIDPRequestToDomain(req *admin_pb.AddJWTIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
Name: req.Name,
|
||||
JWTConfig: addJWTIDPRequestToDomainJWTIDPConfig(req),
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
Type: domain.IDPConfigTypeJWT,
|
||||
AutoRegister: req.AutoRegister,
|
||||
}
|
||||
}
|
||||
|
||||
func addJWTIDPRequestToDomainJWTIDPConfig(req *admin_pb.AddJWTIDPRequest) *domain.JWTIDPConfig {
|
||||
return &domain.JWTIDPConfig{
|
||||
JWTEndpoint: req.JwtEndpoint,
|
||||
Issuer: req.Issuer,
|
||||
KeysEndpoint: req.KeysEndpoint,
|
||||
HeaderName: req.HeaderName,
|
||||
}
|
||||
}
|
||||
|
||||
func updateIDPToDomain(req *admin_pb.UpdateIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
@@ -52,6 +71,16 @@ func updateOIDCConfigToDomain(req *admin_pb.UpdateIDPOIDCConfigRequest) *domain.
|
||||
}
|
||||
}
|
||||
|
||||
func updateJWTConfigToDomain(req *admin_pb.UpdateIDPJWTConfigRequest) *domain.JWTIDPConfig {
|
||||
return &domain.JWTIDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
JWTEndpoint: req.JwtEndpoint,
|
||||
Issuer: req.Issuer,
|
||||
KeysEndpoint: req.KeysEndpoint,
|
||||
HeaderName: req.HeaderName,
|
||||
}
|
||||
}
|
||||
|
||||
func listIDPsToModel(req *admin_pb.ListIDPsRequest) *iam_model.IDPConfigSearchRequest {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
return &iam_model.IDPConfigSearchRequest{
|
||||
|
@@ -46,6 +46,7 @@ func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
||||
"OIDCConfig.AuthorizationEndpoint",
|
||||
"OIDCConfig.TokenEndpoint",
|
||||
"Type", //TODO: default (0) is oidc
|
||||
"JWTConfig",
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -113,6 +114,7 @@ func Test_updateIDPToDomain(t *testing.T) {
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"OIDCConfig",
|
||||
"JWTConfig",
|
||||
"State",
|
||||
"Type", //TODO: type should not be changeable
|
||||
)
|
||||
|
@@ -59,7 +59,7 @@ func ExternalIDPViewToLoginPolicyLinkPb(link *iam_model.IDPProviderView) *idp_pb
|
||||
return &idp_pb.IDPLoginPolicyLink{
|
||||
IdpId: link.IDPConfigID,
|
||||
IdpName: link.Name,
|
||||
IdpType: idp_pb.IDPType_IDP_TYPE_OIDC,
|
||||
IdpType: IDPTypeToPb(link.IDPConfigType),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,20 @@ func ExternalIDPViewToUserLinkPb(link *user_model.ExternalIDPView) *idp_pb.IDPUs
|
||||
ProvidedUserId: link.ExternalUserID,
|
||||
ProvidedUserName: link.UserDisplayName,
|
||||
//TODO: as soon as saml is implemented we need to switch here
|
||||
IdpType: idp_pb.IDPType_IDP_TYPE_OIDC,
|
||||
//IdpType: IDPTypeToPb(link.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func IDPTypeToPb(idpType iam_model.IdpConfigType) idp_pb.IDPType {
|
||||
switch idpType {
|
||||
case iam_model.IDPConfigTypeOIDC:
|
||||
return idp_pb.IDPType_IDP_TYPE_OIDC
|
||||
case iam_model.IDPConfigTypeSAML:
|
||||
return idp_pb.IDPType_IDP_TYPE_UNSPECIFIED
|
||||
case iam_model.IDPConfigTypeJWT:
|
||||
return idp_pb.IDPType_IDP_TYPE_JWT
|
||||
default:
|
||||
return idp_pb.IDPType_IDP_TYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,26 +145,45 @@ func IDPStylingTypeToPb(stylingType domain.IDPConfigStylingType) idp_pb.IDPStyli
|
||||
}
|
||||
}
|
||||
|
||||
func ModelIDPViewToConfigPb(config *iam_model.IDPConfigView) *idp_pb.IDP_OidcConfig {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: ModelMappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: ModelMappingFieldToPb(config.OIDCUsernameMapping),
|
||||
func ModelIDPViewToConfigPb(config *iam_model.IDPConfigView) idp_pb.IDPConfig {
|
||||
if config.IsOIDC {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: ModelMappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: ModelMappingFieldToPb(config.OIDCUsernameMapping),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &idp_pb.IDP_JwtConfig{
|
||||
JwtConfig: &idp_pb.JWTConfig{
|
||||
JwtEndpoint: config.JWTEndpoint,
|
||||
Issuer: config.JWTIssuer,
|
||||
KeysEndpoint: config.JWTKeysEndpoint,
|
||||
HeaderName: config.JWTHeaderName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func IDPViewToConfigPb(config *domain.IDPConfigView) *idp_pb.IDP_OidcConfig {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: MappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: MappingFieldToPb(config.OIDCUsernameMapping),
|
||||
func IDPViewToConfigPb(config *domain.IDPConfigView) idp_pb.IDPConfig {
|
||||
if config.IsOIDC {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: MappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: MappingFieldToPb(config.OIDCUsernameMapping),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &idp_pb.IDP_JwtConfig{
|
||||
JwtConfig: &idp_pb.JWTConfig{
|
||||
JwtEndpoint: config.JWTEndpoint,
|
||||
Issuer: config.JWTIssuer,
|
||||
KeysEndpoint: config.JWTKeysEndpoint,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,22 @@ func (s *Server) AddOrgOIDCIDP(ctx context.Context, req *mgmt_pb.AddOrgOIDCIDPRe
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddOrgJWTIDP(ctx context.Context, req *mgmt_pb.AddOrgJWTIDPRequest) (*mgmt_pb.AddOrgJWTIDPResponse, error) {
|
||||
config, err := s.command.AddIDPConfig(ctx, addJWTIDPRequestToDomain(req), authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.AddOrgJWTIDPResponse{
|
||||
IdpId: config.IDPConfigID,
|
||||
Details: object_pb.AddToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeactivateOrgIDP(ctx context.Context, req *mgmt_pb.DeactivateOrgIDPRequest) (*mgmt_pb.DeactivateOrgIDPResponse, error) {
|
||||
objectDetails, err := s.command.DeactivateIDPConfig(ctx, req.IdpId, authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
@@ -96,3 +112,17 @@ func (s *Server) UpdateOrgIDPOIDCConfig(ctx context.Context, req *mgmt_pb.Update
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateOrgIDPJWTConfig(ctx context.Context, req *mgmt_pb.UpdateOrgIDPJWTConfigRequest) (*mgmt_pb.UpdateOrgIDPJWTConfigResponse, error) {
|
||||
config, err := s.command.ChangeIDPJWTConfig(ctx, updateJWTConfigToDomain(req), authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.UpdateOrgIDPJWTConfigResponse{
|
||||
Details: object_pb.ChangeToDetailsPb(
|
||||
config.Sequence,
|
||||
config.ChangeDate,
|
||||
config.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -12,10 +12,11 @@ import (
|
||||
|
||||
func addOIDCIDPRequestToDomain(req *mgmt_pb.AddOrgOIDCIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
Name: req.Name,
|
||||
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
Type: domain.IDPConfigTypeOIDC,
|
||||
Name: req.Name,
|
||||
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
Type: domain.IDPConfigTypeOIDC,
|
||||
AutoRegister: req.AutoRegister,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +31,25 @@ func addOIDCIDPRequestToDomainOIDCIDPConfig(req *mgmt_pb.AddOrgOIDCIDPRequest) *
|
||||
}
|
||||
}
|
||||
|
||||
func addJWTIDPRequestToDomain(req *mgmt_pb.AddOrgJWTIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
Name: req.Name,
|
||||
JWTConfig: addJWTIDPRequestToDomainJWTIDPConfig(req),
|
||||
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
|
||||
Type: domain.IDPConfigTypeJWT,
|
||||
AutoRegister: req.AutoRegister,
|
||||
}
|
||||
}
|
||||
|
||||
func addJWTIDPRequestToDomainJWTIDPConfig(req *mgmt_pb.AddOrgJWTIDPRequest) *domain.JWTIDPConfig {
|
||||
return &domain.JWTIDPConfig{
|
||||
JWTEndpoint: req.JwtEndpoint,
|
||||
Issuer: req.Issuer,
|
||||
KeysEndpoint: req.KeysEndpoint,
|
||||
HeaderName: req.HeaderName,
|
||||
}
|
||||
}
|
||||
|
||||
func updateIDPToDomain(req *mgmt_pb.UpdateOrgIDPRequest) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
@@ -51,6 +71,16 @@ func updateOIDCConfigToDomain(req *mgmt_pb.UpdateOrgIDPOIDCConfigRequest) *domai
|
||||
}
|
||||
}
|
||||
|
||||
func updateJWTConfigToDomain(req *mgmt_pb.UpdateOrgIDPJWTConfigRequest) *domain.JWTIDPConfig {
|
||||
return &domain.JWTIDPConfig{
|
||||
IDPConfigID: req.IdpId,
|
||||
JWTEndpoint: req.JwtEndpoint,
|
||||
Issuer: req.Issuer,
|
||||
KeysEndpoint: req.KeysEndpoint,
|
||||
HeaderName: req.HeaderName,
|
||||
}
|
||||
}
|
||||
|
||||
func listIDPsToModel(req *mgmt_pb.ListOrgIDPsRequest) *iam_model.IDPConfigSearchRequest {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
return &iam_model.IDPConfigSearchRequest{
|
||||
|
@@ -46,7 +46,7 @@ func Test_addOIDCIDPRequestToDomain(t *testing.T) {
|
||||
"OIDCConfig.AuthorizationEndpoint",
|
||||
"OIDCConfig.TokenEndpoint",
|
||||
"Type", //TODO: default (0) is oidc
|
||||
"AutoRegister",
|
||||
"JWTConfig",
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -114,6 +114,7 @@ func Test_updateIDPToDomain(t *testing.T) {
|
||||
test.AssertFieldsMapped(t, got,
|
||||
"ObjectRoot",
|
||||
"OIDCConfig",
|
||||
"JWTConfig",
|
||||
"State",
|
||||
"Type", //TODO: type should not be changeable
|
||||
)
|
||||
|
Reference in New Issue
Block a user