Skip to content

Commit c59d405

Browse files
committed
Introspect endpoint Authorization Server support
Issue: gh-5200
1 parent ef9c3e4 commit c59d405

File tree

2 files changed

+74
-8
lines changed

2 files changed

+74
-8
lines changed

samples/boot/oauth2authorizationserver/src/main/java/sample/JwkSetConfiguration.java renamed to samples/boot/oauth2authorizationserver/src/main/java/sample/AuthorizationServerConfiguration.java

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,12 +21,15 @@
2121
import java.security.interfaces.RSAPublicKey;
2222
import java.security.spec.RSAPrivateKeySpec;
2323
import java.security.spec.RSAPublicKeySpec;
24+
import java.util.HashMap;
2425
import java.util.LinkedHashMap;
2526
import java.util.Map;
27+
import java.util.stream.Collectors;
2628

2729
import com.nimbusds.jose.jwk.JWKSet;
2830
import com.nimbusds.jose.jwk.RSAKey;
2931

32+
import org.springframework.beans.factory.annotation.Value;
3033
import org.springframework.context.annotation.Bean;
3134
import org.springframework.context.annotation.Configuration;
3235
import org.springframework.security.authentication.AuthenticationManager;
@@ -37,18 +40,23 @@
3740
import org.springframework.security.core.authority.AuthorityUtils;
3841
import org.springframework.security.core.userdetails.User;
3942
import org.springframework.security.core.userdetails.UserDetailsService;
43+
import org.springframework.security.oauth2.common.OAuth2AccessToken;
4044
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
4145
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
4246
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
4347
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
48+
import org.springframework.security.oauth2.provider.OAuth2Authentication;
4449
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpoint;
4550
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
4651
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
4752
import org.springframework.security.oauth2.provider.token.TokenStore;
53+
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
4854
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
4955
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
5056
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
5157
import org.springframework.web.bind.annotation.GetMapping;
58+
import org.springframework.web.bind.annotation.PostMapping;
59+
import org.springframework.web.bind.annotation.RequestParam;
5260
import org.springframework.web.bind.annotation.ResponseBody;
5361

5462
/**
@@ -66,17 +74,20 @@
6674
*/
6775
@EnableAuthorizationServer
6876
@Configuration
69-
public class JwkSetConfiguration extends AuthorizationServerConfigurerAdapter {
77+
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
7078

7179
AuthenticationManager authenticationManager;
7280
KeyPair keyPair;
81+
boolean jwtEnabled;
7382

74-
public JwkSetConfiguration(
83+
public AuthorizationServerConfiguration(
7584
AuthenticationConfiguration authenticationConfiguration,
76-
KeyPair keyPair) throws Exception {
85+
KeyPair keyPair,
86+
@Value("${security.oauth2.authorizationserver.jwt.enabled:true}") boolean jwtEnabled) throws Exception {
7787

7888
this.authenticationManager = authenticationConfiguration.getAuthenticationManager();
7989
this.keyPair = keyPair;
90+
this.jwtEnabled = jwtEnabled;
8091
}
8192

8293
@Override
@@ -94,23 +105,37 @@ public void configure(ClientDetailsServiceConfigurer clients)
94105
.authorizedGrantTypes("password")
95106
.secret("{noop}secret")
96107
.scopes("message:write")
108+
.accessTokenValiditySeconds(600_000_000)
109+
.and()
110+
.withClient("noscopes")
111+
.authorizedGrantTypes("password")
112+
.secret("{noop}secret")
113+
.scopes("none")
97114
.accessTokenValiditySeconds(600_000_000);
98115
// @formatter:on
99116
}
100117

101118
@Override
102-
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
119+
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
103120
// @formatter:off
104121
endpoints
105122
.authenticationManager(this.authenticationManager)
106-
.accessTokenConverter(accessTokenConverter())
107123
.tokenStore(tokenStore());
124+
125+
if (this.jwtEnabled) {
126+
endpoints
127+
.accessTokenConverter(accessTokenConverter());
128+
}
108129
// @formatter:on
109130
}
110131

111132
@Bean
112133
public TokenStore tokenStore() {
113-
return new JwtTokenStore(accessTokenConverter());
134+
if (this.jwtEnabled) {
135+
return new JwtTokenStore(accessTokenConverter());
136+
} else {
137+
return new InMemoryTokenStore();
138+
}
114139
}
115140

116141
@Bean
@@ -137,7 +162,11 @@ protected void configure(HttpSecurity http) throws Exception {
137162
http
138163
.authorizeRequests()
139164
.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()));
141170
}
142171

143172
@Bean
@@ -152,6 +181,41 @@ public UserDetailsService userDetailsService() {
152181
}
153182
}
154183

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+
155219
/**
156220
* Legacy Authorization Server (spring-security-oauth2) does not support any
157221
* <a href target="_blank" href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a> endpoint.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
server.port: 8081
2+
3+
# security.oauth2.authorizationserver.jwt.enabled: false

0 commit comments

Comments
 (0)