fix: improve example & fix userinfo marshal (#132)
* fix: example client should track state, call cli.CodeFlow need context * fix: oidc userinfo can UnmarshalJSON with address * rp Discover use client.Discover * add instruction for example to README.md
This commit is contained in:
parent
a63fbee93d
commit
ff2c164057
6 changed files with 48 additions and 7 deletions
12
README.md
12
README.md
|
@ -21,6 +21,18 @@ Whenever possible we tried to reuse / extend existing packages like `OAuth2 for
|
|||
|
||||
Check the `/example` folder where example code for different scenarios is located.
|
||||
|
||||
```bash
|
||||
# start oidc op server
|
||||
# oidc discovery http://localhost:9998/.well-known/openid-configuration
|
||||
CAOS_OIDC_DEV=1 go run github.com/caos/oidc/example/server/default
|
||||
# start oidc web client
|
||||
CLIENT_ID=web CLIENT_SECRET=web ISSUER=http://localhost:9998/ SCOPES=openid PORT=5556 go run github.com/caos/oidc/example/client/app
|
||||
```
|
||||
|
||||
- browser http://localhost:5556/login will redirect to op server
|
||||
- input id to login
|
||||
- redirect to client app display user info
|
||||
|
||||
## Features
|
||||
|
||||
| | Code Flow | Implicit Flow | Hybrid Flow | Discovery | PKCE | Token Exchange | mTLS | JWT Profile | Refresh Token |
|
||||
|
|
|
@ -43,7 +43,7 @@ func main() {
|
|||
state := func() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
token := cli.CodeFlow(relyingParty, callbackPath, port, state)
|
||||
token := cli.CodeFlow(ctx, relyingParty, callbackPath, port, state)
|
||||
|
||||
client := github.NewClient(relyingParty.OAuthConfig().Client(ctx, token.Token))
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ type AuthRequest struct {
|
|||
Nonce string
|
||||
ClientID string
|
||||
CodeChallenge *oidc.CodeChallenge
|
||||
State string
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetACR() string {
|
||||
|
@ -98,7 +99,7 @@ func (a *AuthRequest) GetScopes() []string {
|
|||
func (a *AuthRequest) SetCurrentScopes(scopes []string) {}
|
||||
|
||||
func (a *AuthRequest) GetState() string {
|
||||
return ""
|
||||
return a.State
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetSubject() string {
|
||||
|
@ -120,7 +121,7 @@ func (s *AuthStorage) Health(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *AuthStorage) CreateAuthRequest(_ context.Context, authReq *oidc.AuthRequest, _ string) (op.AuthRequest, error) {
|
||||
a = &AuthRequest{ID: "id", ClientID: authReq.ClientID, ResponseType: authReq.ResponseType, Nonce: authReq.Nonce, RedirectURI: authReq.RedirectURI}
|
||||
a = &AuthRequest{ID: "id", ClientID: authReq.ClientID, ResponseType: authReq.ResponseType, Nonce: authReq.Nonce, RedirectURI: authReq.RedirectURI, State: authReq.State}
|
||||
if authReq.CodeChallenge != "" {
|
||||
a.CodeChallenge = &oidc.CodeChallenge{
|
||||
Challenge: authReq.CodeChallenge,
|
||||
|
@ -212,7 +213,7 @@ func (s *AuthStorage) GetClientByClientID(_ context.Context, id string) (op.Clie
|
|||
accessTokenType = op.AccessTokenTypeJWT
|
||||
responseTypes = []oidc.ResponseType{oidc.ResponseTypeIDToken, oidc.ResponseTypeIDTokenOnly}
|
||||
}
|
||||
return &ConfClient{ID: id, applicationType: appType, authMethod: authMethod, accessTokenType: accessTokenType, responseTypes: responseTypes, devMode: false}, nil
|
||||
return &ConfClient{ID: id, applicationType: appType, authMethod: authMethod, accessTokenType: accessTokenType, responseTypes: responseTypes, devMode: false, grantTypes: []oidc.GrantType{oidc.GrantTypeCode}}, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) AuthorizeClientIDSecret(_ context.Context, id string, _ string) error {
|
||||
|
|
|
@ -170,17 +170,18 @@ func NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI string, sco
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
endpoints, err := Discover(rp.issuer, rp.httpClient)
|
||||
discoveryConfiguration, err := client.Discover(rp.issuer, rp.httpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoints := GetEndpoints(discoveryConfiguration)
|
||||
rp.oauthConfig.Endpoint = endpoints.Endpoint
|
||||
rp.endpoints = endpoints
|
||||
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
//DefaultRPOpts is the type for providing dynamic options to the DefaultRP
|
||||
//Option is the type for providing dynamic options to the DefaultRP
|
||||
type Option func(*relyingParty) error
|
||||
|
||||
//WithCookieHandler set a `CookieHandler` for securing the various redirects
|
||||
|
|
|
@ -360,6 +360,7 @@ func (i *userinfo) MarshalJSON() ([]byte, error) {
|
|||
func (i *userinfo) UnmarshalJSON(data []byte) error {
|
||||
type Alias userinfo
|
||||
a := &struct {
|
||||
Address *userInfoAddress `json:"address,omitempty"`
|
||||
*Alias
|
||||
UpdatedAt int64 `json:"update_at,omitempty"`
|
||||
}{
|
||||
|
@ -368,7 +369,7 @@ func (i *userinfo) UnmarshalJSON(data []byte) error {
|
|||
if err := json.Unmarshal(data, &a); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Address = a.Address
|
||||
i.UpdatedAt = Time(time.Unix(a.UpdatedAt, 0).UTC())
|
||||
|
||||
if err := json.Unmarshal(data, &i.claims); err != nil {
|
||||
|
|
26
pkg/oidc/userinfo_test.go
Normal file
26
pkg/oidc/userinfo_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserInfoMarshal(t *testing.T) {
|
||||
userinfo := NewUserInfo()
|
||||
userinfo.SetSubject("test")
|
||||
userinfo.SetAddress(NewUserInfoAddress("Test 789\nPostfach 2", "", "", "", "", ""))
|
||||
userinfo.SetEmail("test", true)
|
||||
userinfo.SetPhone("0791234567", true)
|
||||
userinfo.SetName("Test")
|
||||
userinfo.AppendClaims("private_claim", "test")
|
||||
|
||||
marshal, err := json.Marshal(userinfo)
|
||||
out := NewUserInfo()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, json.Unmarshal(marshal, out))
|
||||
assert.Equal(t, userinfo.GetAddress(), out.GetAddress())
|
||||
expected, err := json.Marshal(out)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, marshal)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue