/
warden_local.go
122 lines (103 loc) · 3.54 KB
/
warden_local.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
package warden
import (
"net/http"
"time"
"github.com/Sirupsen/logrus"
"github.com/go-errors/errors"
"github.com/ory-am/fosite"
"github.com/ory-am/hydra/firewall"
"github.com/ory-am/hydra/oauth2"
"github.com/ory-am/ladon"
"golang.org/x/net/context"
)
type LocalWarden struct {
Warden ladon.Warden
OAuth2 fosite.OAuth2Provider
AccessTokenLifespan time.Duration
Issuer string
}
func (w *LocalWarden) TokenFromRequest(r *http.Request) string {
return fosite.AccessTokenFromRequest(r)
}
func (w *LocalWarden) IsAllowed(ctx context.Context, a *ladon.Request) error {
if err := w.Warden.IsAllowed(a); err != nil {
logrus.WithFields(logrus.Fields{
"subject": a.Subject,
"request": a,
"reason": "request denied by policies",
}).WithError(err).Infof("Access denied")
return err
}
return nil
}
func (w *LocalWarden) TokenAllowed(ctx context.Context, token string, a *ladon.Request, scopes ...string) (*firewall.Context, error) {
var session = new(oauth2.Session)
var auth, err = w.OAuth2.ValidateToken(ctx, token, fosite.AccessToken, session, scopes...)
if err != nil {
logrus.WithFields(logrus.Fields{
"subject": a.Subject,
"request": a,
"reason": "token could not be validated",
}).WithError(err).Infof("Access denied")
return nil, err
}
return w.allowed(ctx, a, scopes, auth, session)
}
func (w *LocalWarden) TokenValid(ctx context.Context, token string, scopes ...string) (*firewall.Context, error) {
var session = new(oauth2.Session)
var oauthRequest = fosite.NewAccessRequest(session)
var auth, err = w.OAuth2.ValidateToken(ctx, token, fosite.AccessToken, session, scopes...)
if err != nil {
logrus.WithFields(logrus.Fields{
"scopes": scopes,
"subject": session.Subject,
"audience": oauthRequest.GetClient().GetID(),
"reason": "token validation failed",
}).WithError(err).Infof("Access denied")
return nil, err
}
return w.newContext(auth), nil
}
func (w *LocalWarden) allowed(ctx context.Context, a *ladon.Request, scopes []string, oauthRequest fosite.AccessRequester, session *oauth2.Session) (*firewall.Context, error) {
session = oauthRequest.GetSession().(*oauth2.Session)
if a.Subject != "" && a.Subject != session.Subject {
err := errors.Errorf("Expected subject to be %s but got %s", session.Subject, a.Subject)
logrus.WithFields(logrus.Fields{
"scopes": scopes,
"subject": a.Subject,
"audience": oauthRequest.GetClient().GetID(),
"request": a,
"reason": "subject mismatch",
}).WithError(err).Infof("Access denied")
return nil, err
}
a.Subject = session.Subject
if err := w.Warden.IsAllowed(a); err != nil {
logrus.WithFields(logrus.Fields{
"scopes": scopes,
"subject": a.Subject,
"audience": oauthRequest.GetClient().GetID(),
"request": a,
"reason": "policy effect is deny",
}).WithError(err).Infof("Access denied")
return nil, err
}
return w.newContext(oauthRequest), nil
}
func (w *LocalWarden) newContext(oauthRequest fosite.AccessRequester) *firewall.Context {
session := oauthRequest.GetSession().(*oauth2.Session)
c := &firewall.Context{
Subject: session.Subject,
GrantedScopes: oauthRequest.GetGrantedScopes(),
Issuer: w.Issuer,
Audience: oauthRequest.GetClient().GetID(),
IssuedAt: oauthRequest.GetRequestedAt(),
ExpiresAt: session.AccessTokenExpiresAt(oauthRequest.GetRequestedAt().Add(w.AccessTokenLifespan)),
Extra: session.Extra,
}
logrus.WithFields(logrus.Fields{
"subject": c.Subject,
"audience": oauthRequest.GetClient().GetID(),
}).Infof("Access granted")
return c
}