forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
authenticator.go
147 lines (123 loc) · 4.81 KB
/
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package handlers
import (
"net/http"
"github.com/RangelReale/osin"
"github.com/golang/glog"
"github.com/openshift/origin/pkg/auth/api"
"github.com/openshift/origin/pkg/auth/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
)
// AuthorizeAuthenticator implements osinserver.AuthorizeHandler to ensure requests are authenticated
type AuthorizeAuthenticator struct {
request authenticator.Request
handler AuthenticationHandler
errorHandler AuthenticationErrorHandler
}
// NewAuthorizeAuthenticator returns a new Authenticator
func NewAuthorizeAuthenticator(request authenticator.Request, handler AuthenticationHandler, errorHandler AuthenticationErrorHandler) *AuthorizeAuthenticator {
return &AuthorizeAuthenticator{request, handler, errorHandler}
}
type TokenMaxAgeSeconds interface {
// GetTokenMaxAgeSeconds returns the max age of the token in seconds.
// 0 means no expiration.
// nil means to use the default expiration.
GetTokenMaxAgeSeconds() *int32
}
// HandleAuthorize implements osinserver.AuthorizeHandler to ensure the AuthorizeRequest is authenticated.
// If the request is authenticated, UserData and Authorized are set and false is returned.
// If the request is not authenticated, the auth handler is called and the request is not authorized
func (h *AuthorizeAuthenticator) HandleAuthorize(ar *osin.AuthorizeRequest, resp *osin.Response, w http.ResponseWriter) (bool, error) {
info, ok, err := h.request.AuthenticateRequest(ar.HttpRequest)
if err != nil {
glog.V(4).Infof("OAuth authentication error: %v", err)
return h.errorHandler.AuthenticationError(err, w, ar.HttpRequest)
}
if !ok {
return h.handler.AuthenticationNeeded(ar.Client, w, ar.HttpRequest)
}
glog.V(4).Infof("OAuth authentication succeeded: %#v", info)
ar.UserData = info
ar.Authorized = true
// If requesting a token directly, optionally override the expiration
if ar.Type == osin.TOKEN {
if e, ok := ar.Client.(TokenMaxAgeSeconds); ok {
if maxAge := e.GetTokenMaxAgeSeconds(); maxAge != nil {
ar.Expiration = *maxAge
}
}
}
return false, nil
}
// AccessAuthenticator implements osinserver.AccessHandler to ensure non-token requests are authenticated
type AccessAuthenticator struct {
password authenticator.Password
assertion authenticator.Assertion
client authenticator.Client
}
// NewAccessAuthenticator returns a new AccessAuthenticator
func NewAccessAuthenticator(password authenticator.Password, assertion authenticator.Assertion, client authenticator.Client) *AccessAuthenticator {
return &AccessAuthenticator{password, assertion, client}
}
// HandleAccess implements osinserver.AccessHandler
func (h *AccessAuthenticator) HandleAccess(ar *osin.AccessRequest, w http.ResponseWriter) error {
var (
info user.Info
ok bool
err error
)
switch ar.Type {
case osin.AUTHORIZATION_CODE, osin.REFRESH_TOKEN:
// auth codes and refresh tokens are assumed allowed
ok = true
case osin.PASSWORD:
info, ok, err = h.password.AuthenticatePassword(ar.Username, ar.Password)
case osin.ASSERTION:
info, ok, err = h.assertion.AuthenticateAssertion(ar.AssertionType, ar.Assertion)
case osin.CLIENT_CREDENTIALS:
info, ok, err = h.client.AuthenticateClient(ar.Client)
default:
glog.Warningf("Received unknown access token type: %s", ar.Type)
}
if err != nil {
glog.V(4).Infof("Unable to authenticate %s: %v", ar.Type, err)
return err
}
if ok {
// Disable refresh_token generation
ar.GenerateRefresh = false
ar.Authorized = true
if info != nil {
ar.AccessData.UserData = info
}
if e, ok := ar.Client.(TokenMaxAgeSeconds); ok {
if maxAge := e.GetTokenMaxAgeSeconds(); maxAge != nil {
ar.Expiration = *maxAge
}
}
}
return nil
}
// NewDenyAccessAuthenticator returns an AccessAuthenticator which rejects all non-token access requests
func NewDenyAccessAuthenticator() *AccessAuthenticator {
return &AccessAuthenticator{Deny, Deny, Deny}
}
// Deny implements Password, Assertion, and Client authentication to deny all requests
var Deny = &fixedAuthenticator{false}
// Allow implements Password, Assertion, and Client authentication to allow all requests
var Allow = &fixedAuthenticator{true}
// fixedAuthenticator implements Password, Assertion, and Client authentication to return a fixed response
type fixedAuthenticator struct {
allow bool
}
// AuthenticatePassword implements authenticator.Password
func (f *fixedAuthenticator) AuthenticatePassword(user, password string) (user.Info, bool, error) {
return nil, f.allow, nil
}
// AuthenticateAssertion implements authenticator.Assertion
func (f *fixedAuthenticator) AuthenticateAssertion(assertionType, data string) (user.Info, bool, error) {
return nil, f.allow, nil
}
// AuthenticateClient implements authenticator.Client
func (f *fixedAuthenticator) AuthenticateClient(client api.Client) (user.Info, bool, error) {
return nil, f.allow, nil
}