authentification OpenID Connect (Keycloak) : flux authorization code, state signé, validation du token ID via JWKS, provisioning automatique des utilisateurs
This commit is contained in:
1 parent
51bbb45b32
commit
bedb6c98e7
15 files changed
+1057
-23
No files matched your search
@@ -17,20 +17,31 @@ var (
|
||||
|
||||
type Service struct {
|
||||
authenticators map[string]Authenticator // "password" -> ..., "oidc" -> ...
|
||||
oidcManager OIDCManager
|
||||
tokenManager TokenManager
|
||||
userRepository domain.UserRepository
|
||||
oidcRepository domain.OIDCProviderRepository
|
||||
settingsRepository domain.SettingsRepository
|
||||
}
|
||||
|
||||
func NewService(
|
||||
settingsRepository domain.SettingsRepository,
|
||||
userRepository domain.UserRepository,
|
||||
oidcRepository domain.OIDCProviderRepository,
|
||||
tokenManager TokenManager,
|
||||
authenticators map[string]Authenticator,
|
||||
) *Service {
|
||||
return &Service{
|
||||
service := &Service{
|
||||
authenticators: authenticators,
|
||||
tokenManager: tokenManager,
|
||||
userRepository: userRepository,
|
||||
oidcRepository: oidcRepository,
|
||||
settingsRepository: settingsRepository,
|
||||
}
|
||||
if manager, ok := authenticators["oidc"].(OIDCManager); ok {
|
||||
service.oidcManager = manager
|
||||
}
|
||||
return service
|
||||
}
|
||||
|
||||
func (s *Service) Login(ctx context.Context, creds Credentials) (*Session, error) {
|
||||
@@ -72,3 +83,37 @@ func (s *Service) Register(registration Registration) (*Session, error) {
|
||||
func (s *Service) Status(session *Session) (*domain.User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ListOIDCProviders retourne les fournisseurs OpenID Connect enregistrés,
|
||||
// sans exposer le secret client (champ marqué json:"-").
|
||||
func (s *Service) ListOIDCProviders() ([]*domain.OIDCProvider, error) {
|
||||
return s.oidcRepository.ListOIDCProviders()
|
||||
}
|
||||
|
||||
// OIDCAuthorizeURL construit l'URL d'autorisation du fournisseur, avec un
|
||||
// state signé transportant l'id du fournisseur.
|
||||
func (s *Service) OIDCAuthorizeURL(ctx context.Context, providerID string, redirectURI string) (string, error) {
|
||||
provider, err := s.oidcRepository.FindOIDCProvider(providerID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unknown oidc provider: %s", providerID)
|
||||
}
|
||||
state, err := s.tokenManager.GenerateStateToken(providerID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.oidcManager.AuthorizeURL(ctx, provider, redirectURI, state)
|
||||
}
|
||||
|
||||
// OIDCCallback traite le retour du fournisseur: vérifie le state, échange le
|
||||
// code d'autorisation et délivre une session applicative.
|
||||
func (s *Service) OIDCCallback(ctx context.Context, state string, code string, redirectURI string) (*Session, error) {
|
||||
providerID, err := s.tokenManager.ParseStateToken(state)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid oidc state: %s", err)
|
||||
}
|
||||
provider, err := s.oidcRepository.FindOIDCProvider(providerID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unknown oidc provider: %s", providerID)
|
||||
}
|
||||
return s.oidcManager.ExchangeCode(ctx, provider, code, redirectURI)
|
||||
}
|
||||
Reference in new issue
Block a user