/
oidc-authenticator.go
96 lines (83 loc) · 2.69 KB
/
oidc-authenticator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package oidc
import (
"context"
"errors"
"reflect"
auth_oidc "github.com/fluffy-bunny/grpcdotnetgo/pkg/auth/oidc"
contracts_oauth2 "github.com/fluffy-bunny/grpcdotnetgo/pkg/contracts/oauth2"
contracts_oidc "github.com/fluffy-bunny/grpcdotnetgo/pkg/contracts/oidc"
"github.com/rs/zerolog/log"
"github.com/coreos/go-oidc/v3/oidc"
di "github.com/fluffy-bunny/sarulabsdi"
"golang.org/x/oauth2"
)
type (
service struct {
*oidc.Provider
oauth2.Config
GetOIDCAuthenticatorConfig contracts_oidc.GetOIDCAuthenticatorConfig `inject:""`
oidcProviderEx *auth_oidc.Provider
issuer string
}
)
func assertImplementation() {
var _ contracts_oidc.IOIDCAuthenticator = (*service)(nil)
}
var reflectType = reflect.TypeOf((*service)(nil))
// AddSingletonIOIDCAuthenticator registers the *service as a singleton.
func AddSingletonIOIDCAuthenticator(builder *di.Builder) {
contracts_oidc.AddSingletonIOIDCAuthenticator(builder, reflectType, contracts_oauth2.ReflectTypeIOAuth2Authenticator)
}
func (s *service) Ctor() {
log.Info().Msg("OIDC Authenticator created")
config := s.GetOIDCAuthenticatorConfig()
s.issuer = "https://"
if config.Insecure {
s.issuer = "http://"
}
s.issuer += config.Domain + "/"
log.Info().Msgf("issuer: %s", s.issuer)
oidcProviderEx, err := auth_oidc.NewProvider(context.Background(), s.issuer)
if err != nil {
log.Info().Err(err).Msg("failed to create oidc provider")
panic(err)
}
s.oidcProviderEx = oidcProviderEx
provider, err := oidc.NewProvider(
context.Background(),
s.issuer,
)
if err != nil {
log.Info().Err(err).Msg(" failed to create oidc provider")
panic(err)
}
s.Provider = provider
conf := oauth2.Config{
ClientID: config.ClientID,
ClientSecret: config.ClientSecret,
RedirectURL: config.CallbackURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile"},
}
s.Config = conf
}
func (s *service) ValidateJWTAccessToken(accessToken string) (*auth_oidc.AccessToken, error) {
verifier := auth_oidc.NewJWTAccessTokenVerifier(s.issuer, s.oidcProviderEx.GetRemoteKeySet(), &oidc.Config{
SkipClientIDCheck: true,
})
return verifier.Verify(context.Background(), accessToken)
}
func (s *service) VerifyIDToken(ctx context.Context, token *oauth2.Token) (*oidc.IDToken, error) {
rawIDToken, ok := token.Extra("id_token").(string)
if !ok {
return nil, errors.New("no id_token field in oauth2 token")
}
oidcConfig := &oidc.Config{
ClientID: s.ClientID,
}
return s.Verifier(oidcConfig).Verify(ctx, rawIDToken)
}
func (s *service) GetTokenSource(ctx context.Context, token *oauth2.Token) oauth2.TokenSource {
ts := s.Config.TokenSource(ctx, token)
return ts
}