This repository has been archived by the owner on Oct 23, 2024. It is now read-only.
forked from arrikto/oidc-authservice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
authenticator_opaque.go
99 lines (79 loc) · 2.92 KB
/
authenticator_opaque.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
97
98
99
package main
import (
"net/http"
oidc "github.com/coreos/go-oidc"
"github.com/pkg/errors"
"golang.org/x/oauth2"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
)
type opaqueTokenAuthenticator struct {
header string // header name where opaque access token is stored
caBundle []byte
provider *oidc.Provider
oauth2Config *oauth2.Config
userIDClaim string // retrieve the userid claim
groupsClaim string // retrieve the groups claim
}
func (s *opaqueTokenAuthenticator) AuthenticateRequest(r *http.Request) (*authenticator.Response, bool, error) {
logger := loggerForRequest(r, "opaque access token authenticator")
// get id-token from header
bearer := getBearerToken(r.Header.Get(s.header))
if len(bearer) == 0 {
logger.Info("No bearer token found")
return nil, false, nil
}
opaque := &oauth2.Token {
AccessToken: bearer,
TokenType: "Bearer",
}
ctx := setTLSContext(r.Context(), s.caBundle)
userInfo, err := GetUserInfo(ctx, s.provider, s.oauth2Config.TokenSource(ctx, opaque))
if err != nil {
var reqErr *requestError
if !errors.As(err, &reqErr) {
return nil, false, errors.Wrap(err, "UserInfo request failed unexpectedly")
}
return nil, false, errors.Wrapf(err, "UserInfo request failed with code '%d'", reqErr.Response.StatusCode)
}
// Retrieve the USERID_CLAIM and the GROUPS_CLAIM
var claims map[string]interface{}
if claimErr := userInfo.Claims(&claims); claimErr != nil {
logger.Errorf("Retrieving user claims failed: %v", claimErr)
return nil, false, &authenticatorSpecificError{Err: claimErr}
}
userID, groups, claimErr := s.retrieveUserIDGroupsClaims(claims)
if claimErr != nil {
return nil, false, &authenticatorSpecificError{Err: claimErr}
}
// Authentication using header successfully completed
extra := map[string][]string{"auth-method": {"header"}}
resp := &authenticator.Response{
User: &user.DefaultInfo{
Name: userID,
Groups: groups,
Extra: extra,
},
}
return resp, true, nil
}
// Retrieve the USERID_CLAIM and the GROUPS_CLAIM from the /userinfo response
func (s *opaqueTokenAuthenticator) retrieveUserIDGroupsClaims(claims map[string]interface{}) (string, []string, error){
if claims[s.userIDClaim] == nil {
claimErr := errors.New("USERID_CLAIM not found in the response of the userinfo endpoint")
return "", []string{}, claimErr
}
groups := []string{}
groupsClaim := claims[s.groupsClaim]
if groupsClaim == nil {
claimErr := errors.New("GROUPS_CLAIM not found in the response of the userinfo endpoint")
return "", []string{}, claimErr
}
groups = interfaceSliceToStringSlice(groupsClaim.([]interface{}))
return claims[s.userIDClaim].(string), groups, nil
}
// The Opaque Access Token Authenticator implements the Cacheable
// interface with the getCacheKey().
func (s *opaqueTokenAuthenticator) getCacheKey(r *http.Request) (string) {
return getBearerToken(r.Header.Get("Authorization"))
}