forked from ory/hydra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler_oauth2_factory.go
137 lines (123 loc) · 4.18 KB
/
handler_oauth2_factory.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
package server
import (
"fmt"
"net/url"
"os"
"github.com/gorilla/sessions"
"github.com/julienschmidt/httprouter"
"github.com/ory/fosite"
"github.com/ory/fosite/compose"
"github.com/ory/herodot"
"github.com/ory/hydra/client"
"github.com/ory/hydra/config"
"github.com/ory/hydra/jwk"
"github.com/ory/hydra/oauth2"
"github.com/ory/hydra/pkg"
"github.com/pkg/errors"
)
func injectFositeStore(c *config.Config, clients client.Manager) {
var ctx = c.Context()
var store pkg.FositeStorer
switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
store = &oauth2.FositeMemoryStore{
Manager: clients,
AuthorizeCodes: make(map[string]fosite.Requester),
IDSessions: make(map[string]fosite.Requester),
AccessTokens: make(map[string]fosite.Requester),
RefreshTokens: make(map[string]fosite.Requester),
}
break
case *config.SQLConnection:
store = &oauth2.FositeSQLStore{
DB: con.GetDatabase(),
Manager: clients,
L: c.GetLogger(),
}
break
case *config.PluginConnection:
var err error
if store, err = con.NewOAuth2Manager(clients); err != nil {
c.GetLogger().Fatalf("Could not load client manager plugin %s", err)
}
break
default:
panic("Unknown connection type.")
}
ctx.FositeStore = store
}
func newOAuth2Provider(c *config.Config, km jwk.Manager) fosite.OAuth2Provider {
var ctx = c.Context()
var store = ctx.FositeStore
createRS256KeysIfNotExist(c, oauth2.OpenIDConnectKeyName, "private", "sig")
keys, err := km.GetKey(oauth2.OpenIDConnectKeyName, "private")
if errors.Cause(err) == pkg.ErrNotFound {
c.GetLogger().Warnln("Could not find OpenID Connect signing keys. Generating a new keypair...")
keys, err = new(jwk.RS256Generator).Generate("")
pkg.Must(err, "Could not generate signing key for OpenID Connect")
km.AddKeySet(oauth2.OpenIDConnectKeyName, keys)
c.GetLogger().Infoln("Keypair generated.")
c.GetLogger().Warnln("WARNING: Automated key creation causes low entropy. Replace the keys as soon as possible.")
} else if err != nil {
fmt.Fprintf(os.Stderr, `Could not fetch signing key for OpenID Connect - did you forget to run "hydra migrate sql" or forget to set the SYSTEM_SECRET? Got error: %s`+"\n", err.Error())
os.Exit(1)
}
rsaKey := jwk.MustRSAPrivate(jwk.First(keys.Keys))
fc := &compose.Config{
AccessTokenLifespan: c.GetAccessTokenLifespan(),
AuthorizeCodeLifespan: c.GetAuthCodeLifespan(),
IDTokenLifespan: c.GetIDTokenLifespan(),
HashCost: c.BCryptWorkFactor,
}
return compose.Compose(
fc,
store,
&compose.CommonStrategy{
CoreStrategy: compose.NewOAuth2HMACStrategy(fc, c.GetSystemSecret()),
OpenIDConnectTokenStrategy: compose.NewOpenIDConnectStrategy(rsaKey),
},
nil,
compose.OAuth2AuthorizeExplicitFactory,
compose.OAuth2AuthorizeImplicitFactory,
compose.OAuth2ClientCredentialsGrantFactory,
compose.OAuth2RefreshTokenGrantFactory,
compose.OpenIDConnectExplicitFactory,
compose.OpenIDConnectHybridFactory,
compose.OpenIDConnectImplicitFactory,
compose.OAuth2TokenRevocationFactory,
compose.OAuth2TokenIntrospectionFactory,
)
}
func newOAuth2Handler(c *config.Config, router *httprouter.Router, km jwk.Manager, o fosite.OAuth2Provider) *oauth2.Handler {
if c.ConsentURL == "" {
proto := "https"
if c.ForceHTTP {
proto = "http"
}
host := "localhost"
if c.BindHost != "" {
host = c.BindHost
}
c.ConsentURL = fmt.Sprintf("%s://%s:%d/oauth2/consent", proto, host, c.BindPort)
}
consentURL, err := url.Parse(c.ConsentURL)
pkg.Must(err, "Could not parse consent url %s.", c.ConsentURL)
handler := &oauth2.Handler{
ForcedHTTP: c.ForceHTTP,
OAuth2: o,
Consent: &oauth2.DefaultConsentStrategy{
Issuer: c.Issuer,
KeyManager: km,
DefaultChallengeLifespan: c.GetChallengeTokenLifespan(),
DefaultIDTokenLifespan: c.GetIDTokenLifespan(),
},
ConsentURL: *consentURL,
H: herodot.NewJSONWriter(c.GetLogger()),
AccessTokenLifespan: c.GetAccessTokenLifespan(),
CookieStore: sessions.NewCookieStore(c.GetCookieSecret()),
Issuer: c.Issuer,
L: c.GetLogger(),
}
handler.SetRoutes(router)
return handler
}