docs(example): implement OpenID Provider (#165)
* chore(example): implement OpenID Provider * jwt profile and fixes * some comments * remove old op example * fix code flow example * add service user and update readme * fix password for example use * ignore example and mock folders for code coverage * Update example/server/internal/storage.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update client.go Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
parent
c195452bb0
commit
885fe0d45c
13 changed files with 1280 additions and 427 deletions
203
example/server/internal/oidc.go
Normal file
203
example/server/internal/oidc.go
Normal file
|
@ -0,0 +1,203 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/caos/oidc/pkg/op"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
)
|
||||
|
||||
const (
|
||||
//CustomScope is an example for how to use custom scopes in this library
|
||||
//(in this scenario, when requested, it will return a custom claim)
|
||||
CustomScope = "custom_scope"
|
||||
|
||||
//CustomClaim is an example for how to return custom claims with this library
|
||||
CustomClaim = "custom_claim"
|
||||
)
|
||||
|
||||
type AuthRequest struct {
|
||||
ID string
|
||||
CreationDate time.Time
|
||||
ApplicationID string
|
||||
CallbackURI string
|
||||
TransferState string
|
||||
Prompt []string
|
||||
UiLocales []language.Tag
|
||||
LoginHint string
|
||||
MaxAuthAge *time.Duration
|
||||
UserID string
|
||||
Scopes []string
|
||||
ResponseType oidc.ResponseType
|
||||
Nonce string
|
||||
CodeChallenge *OIDCCodeChallenge
|
||||
|
||||
passwordChecked bool
|
||||
authTime time.Time
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetID() string {
|
||||
return a.ID
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetACR() string {
|
||||
return "" //we won't handle acr in this example
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetAMR() []string {
|
||||
//this example only uses password for authentication
|
||||
if a.passwordChecked {
|
||||
return []string{"pwd"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetAudience() []string {
|
||||
return []string{a.ApplicationID} //this example will always just use the client_id as audience
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetAuthTime() time.Time {
|
||||
return a.authTime
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetClientID() string {
|
||||
return a.ApplicationID
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetCodeChallenge() *oidc.CodeChallenge {
|
||||
return CodeChallengeToOIDC(a.CodeChallenge)
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetNonce() string {
|
||||
return a.Nonce
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetRedirectURI() string {
|
||||
return a.CallbackURI
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetResponseType() oidc.ResponseType {
|
||||
return a.ResponseType
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetResponseMode() oidc.ResponseMode {
|
||||
return "" //we won't handle response mode in this example
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetScopes() []string {
|
||||
return a.Scopes
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetState() string {
|
||||
return a.TransferState
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetSubject() string {
|
||||
return a.UserID
|
||||
}
|
||||
|
||||
func (a *AuthRequest) Done() bool {
|
||||
return a.passwordChecked //this example only uses password for authentication
|
||||
}
|
||||
|
||||
func PromptToInternal(oidcPrompt oidc.SpaceDelimitedArray) []string {
|
||||
prompts := make([]string, len(oidcPrompt))
|
||||
for _, oidcPrompt := range oidcPrompt {
|
||||
switch oidcPrompt {
|
||||
case oidc.PromptNone,
|
||||
oidc.PromptLogin,
|
||||
oidc.PromptConsent,
|
||||
oidc.PromptSelectAccount:
|
||||
prompts = append(prompts, oidcPrompt)
|
||||
}
|
||||
}
|
||||
return prompts
|
||||
}
|
||||
|
||||
func MaxAgeToInternal(maxAge *uint) *time.Duration {
|
||||
if maxAge == nil {
|
||||
return nil
|
||||
}
|
||||
dur := time.Duration(*maxAge) * time.Second
|
||||
return &dur
|
||||
}
|
||||
|
||||
func authRequestToInternal(authReq *oidc.AuthRequest, userID string) *AuthRequest {
|
||||
return &AuthRequest{
|
||||
CreationDate: time.Now(),
|
||||
ApplicationID: authReq.ClientID,
|
||||
CallbackURI: authReq.RedirectURI,
|
||||
TransferState: authReq.State,
|
||||
Prompt: PromptToInternal(authReq.Prompt),
|
||||
UiLocales: authReq.UILocales,
|
||||
LoginHint: authReq.LoginHint,
|
||||
MaxAuthAge: MaxAgeToInternal(authReq.MaxAge),
|
||||
UserID: userID,
|
||||
Scopes: authReq.Scopes,
|
||||
ResponseType: authReq.ResponseType,
|
||||
Nonce: authReq.Nonce,
|
||||
CodeChallenge: &OIDCCodeChallenge{
|
||||
Challenge: authReq.CodeChallenge,
|
||||
Method: string(authReq.CodeChallengeMethod),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type OIDCCodeChallenge struct {
|
||||
Challenge string
|
||||
Method string
|
||||
}
|
||||
|
||||
func CodeChallengeToOIDC(challenge *OIDCCodeChallenge) *oidc.CodeChallenge {
|
||||
if challenge == nil {
|
||||
return nil
|
||||
}
|
||||
challengeMethod := oidc.CodeChallengeMethodPlain
|
||||
if challenge.Method == "S256" {
|
||||
challengeMethod = oidc.CodeChallengeMethodS256
|
||||
}
|
||||
return &oidc.CodeChallenge{
|
||||
Challenge: challenge.Challenge,
|
||||
Method: challengeMethod,
|
||||
}
|
||||
}
|
||||
|
||||
//RefreshTokenRequestFromBusiness will simply wrap the internal RefreshToken to implement the op.RefreshTokenRequest interface
|
||||
func RefreshTokenRequestFromBusiness(token *RefreshToken) op.RefreshTokenRequest {
|
||||
return &RefreshTokenRequest{token}
|
||||
}
|
||||
|
||||
type RefreshTokenRequest struct {
|
||||
*RefreshToken
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetAMR() []string {
|
||||
return r.AMR
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetAudience() []string {
|
||||
return r.Audience
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetAuthTime() time.Time {
|
||||
return r.AuthTime
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetClientID() string {
|
||||
return r.ApplicationID
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetScopes() []string {
|
||||
return r.Scopes
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) GetSubject() string {
|
||||
return r.UserID
|
||||
}
|
||||
|
||||
func (r *RefreshTokenRequest) SetCurrentScopes(scopes []string) {
|
||||
r.Scopes = scopes
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue