1
1
/*
2
- * Copyright 2002-2018 the original author or authors.
2
+ * Copyright 2002-2019 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
21
21
import java .security .interfaces .RSAPublicKey ;
22
22
import java .security .spec .RSAPrivateKeySpec ;
23
23
import java .security .spec .RSAPublicKeySpec ;
24
+ import java .util .HashMap ;
24
25
import java .util .LinkedHashMap ;
25
26
import java .util .Map ;
27
+ import java .util .stream .Collectors ;
26
28
27
29
import com .nimbusds .jose .jwk .JWKSet ;
28
30
import com .nimbusds .jose .jwk .RSAKey ;
29
31
32
+ import org .springframework .beans .factory .annotation .Value ;
30
33
import org .springframework .context .annotation .Bean ;
31
34
import org .springframework .context .annotation .Configuration ;
32
35
import org .springframework .security .authentication .AuthenticationManager ;
37
40
import org .springframework .security .core .authority .AuthorityUtils ;
38
41
import org .springframework .security .core .userdetails .User ;
39
42
import org .springframework .security .core .userdetails .UserDetailsService ;
43
+ import org .springframework .security .oauth2 .common .OAuth2AccessToken ;
40
44
import org .springframework .security .oauth2 .config .annotation .configurers .ClientDetailsServiceConfigurer ;
41
45
import org .springframework .security .oauth2 .config .annotation .web .configuration .AuthorizationServerConfigurerAdapter ;
42
46
import org .springframework .security .oauth2 .config .annotation .web .configuration .EnableAuthorizationServer ;
43
47
import org .springframework .security .oauth2 .config .annotation .web .configurers .AuthorizationServerEndpointsConfigurer ;
48
+ import org .springframework .security .oauth2 .provider .OAuth2Authentication ;
44
49
import org .springframework .security .oauth2 .provider .endpoint .FrameworkEndpoint ;
45
50
import org .springframework .security .oauth2 .provider .token .DefaultAccessTokenConverter ;
46
51
import org .springframework .security .oauth2 .provider .token .DefaultUserAuthenticationConverter ;
47
52
import org .springframework .security .oauth2 .provider .token .TokenStore ;
53
+ import org .springframework .security .oauth2 .provider .token .store .InMemoryTokenStore ;
48
54
import org .springframework .security .oauth2 .provider .token .store .JwtAccessTokenConverter ;
49
55
import org .springframework .security .oauth2 .provider .token .store .JwtTokenStore ;
50
56
import org .springframework .security .provisioning .InMemoryUserDetailsManager ;
51
57
import org .springframework .web .bind .annotation .GetMapping ;
58
+ import org .springframework .web .bind .annotation .PostMapping ;
59
+ import org .springframework .web .bind .annotation .RequestParam ;
52
60
import org .springframework .web .bind .annotation .ResponseBody ;
53
61
54
62
/**
66
74
*/
67
75
@ EnableAuthorizationServer
68
76
@ Configuration
69
- public class JwkSetConfiguration extends AuthorizationServerConfigurerAdapter {
77
+ public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
70
78
71
79
AuthenticationManager authenticationManager ;
72
80
KeyPair keyPair ;
81
+ boolean jwtEnabled ;
73
82
74
- public JwkSetConfiguration (
83
+ public AuthorizationServerConfiguration (
75
84
AuthenticationConfiguration authenticationConfiguration ,
76
- KeyPair keyPair ) throws Exception {
85
+ KeyPair keyPair ,
86
+ @ Value ("${security.oauth2.authorizationserver.jwt.enabled:true}" ) boolean jwtEnabled ) throws Exception {
77
87
78
88
this .authenticationManager = authenticationConfiguration .getAuthenticationManager ();
79
89
this .keyPair = keyPair ;
90
+ this .jwtEnabled = jwtEnabled ;
80
91
}
81
92
82
93
@ Override
@@ -94,23 +105,37 @@ public void configure(ClientDetailsServiceConfigurer clients)
94
105
.authorizedGrantTypes ("password" )
95
106
.secret ("{noop}secret" )
96
107
.scopes ("message:write" )
108
+ .accessTokenValiditySeconds (600_000_000 )
109
+ .and ()
110
+ .withClient ("noscopes" )
111
+ .authorizedGrantTypes ("password" )
112
+ .secret ("{noop}secret" )
113
+ .scopes ("none" )
97
114
.accessTokenValiditySeconds (600_000_000 );
98
115
// @formatter:on
99
116
}
100
117
101
118
@ Override
102
- public void configure (AuthorizationServerEndpointsConfigurer endpoints ) {
119
+ public void configure (AuthorizationServerEndpointsConfigurer endpoints ) throws Exception {
103
120
// @formatter:off
104
121
endpoints
105
122
.authenticationManager (this .authenticationManager )
106
- .accessTokenConverter (accessTokenConverter ())
107
123
.tokenStore (tokenStore ());
124
+
125
+ if (this .jwtEnabled ) {
126
+ endpoints
127
+ .accessTokenConverter (accessTokenConverter ());
128
+ }
108
129
// @formatter:on
109
130
}
110
131
111
132
@ Bean
112
133
public TokenStore tokenStore () {
113
- return new JwtTokenStore (accessTokenConverter ());
134
+ if (this .jwtEnabled ) {
135
+ return new JwtTokenStore (accessTokenConverter ());
136
+ } else {
137
+ return new InMemoryTokenStore ();
138
+ }
114
139
}
115
140
116
141
@ Bean
@@ -137,7 +162,11 @@ protected void configure(HttpSecurity http) throws Exception {
137
162
http
138
163
.authorizeRequests ()
139
164
.mvcMatchers ("/.well-known/jwks.json" ).permitAll ()
140
- .anyRequest ().authenticated ();
165
+ .anyRequest ().authenticated ()
166
+ .and ()
167
+ .httpBasic ()
168
+ .and ()
169
+ .csrf ().ignoringRequestMatchers (request -> "/introspect" .equals (request .getRequestURI ()));
141
170
}
142
171
143
172
@ Bean
@@ -152,6 +181,41 @@ public UserDetailsService userDetailsService() {
152
181
}
153
182
}
154
183
184
+ /**
185
+ * Legacy Authorization Server (spring-security-oauth2) does not support any
186
+ * Token Introspection endpoint.
187
+ *
188
+ * This class adds ad-hoc support in order to better support the other samples in the repo.
189
+ */
190
+ @ FrameworkEndpoint
191
+ class IntrospectEndpoint {
192
+ TokenStore tokenStore ;
193
+
194
+ public IntrospectEndpoint (TokenStore tokenStore ) {
195
+ this .tokenStore = tokenStore ;
196
+ }
197
+
198
+ @ PostMapping ("/introspect" )
199
+ @ ResponseBody
200
+ public Map <String , Object > introspect (@ RequestParam ("token" ) String token ) {
201
+ OAuth2AccessToken accessToken = this .tokenStore .readAccessToken (token );
202
+ Map <String , Object > attributes = new HashMap <>();
203
+ if (accessToken == null || accessToken .isExpired ()) {
204
+ attributes .put ("active" , false );
205
+ return attributes ;
206
+ }
207
+
208
+ OAuth2Authentication authentication = this .tokenStore .readAuthentication (token );
209
+
210
+ attributes .put ("active" , true );
211
+ attributes .put ("exp" , accessToken .getExpiration ().getTime ());
212
+ attributes .put ("scope" , accessToken .getScope ().stream ().collect (Collectors .joining (" " )));
213
+ attributes .put ("sub" , authentication .getName ());
214
+
215
+ return attributes ;
216
+ }
217
+ }
218
+
155
219
/**
156
220
* Legacy Authorization Server (spring-security-oauth2) does not support any
157
221
* <a href target="_blank" href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a> endpoint.
0 commit comments