Skip to content

Commit aee5e27

Browse files
committed
Add OAuth2TokenAttributesAuthenticationConverter
Fixes: spring-projectsgh-6830
1 parent 04d981e commit aee5e27

File tree

3 files changed

+76
-28
lines changed

3 files changed

+76
-28
lines changed

oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/OAuth2TokenAttributes.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,25 @@
2525
* @author Clement Ng
2626
* @since 5.2
2727
*/
28-
public final class OAuth2TokenAttributes {
28+
public class OAuth2TokenAttributes {
29+
private final String token;
2930
private final Map<String, Object> attributes;
3031

3132
/**
3233
* Constructs an {@code OAuth2TokenAttributes} using the provided parameters.
3334
*
35+
* @param token the OAuth 2.0 token
3436
* @param attributes the attributes of the OAuth 2.0 token
3537
*/
36-
public OAuth2TokenAttributes(Map<String, Object> attributes) {
38+
public OAuth2TokenAttributes(String token, Map<String, Object> attributes) {
39+
this.token = token;
3740
this.attributes = Collections.unmodifiableMap(attributes);
3841
}
3942

43+
public String getToken() {
44+
return this.token;
45+
}
46+
4047
/**
4148
* Gets the attributes of the OAuth 2.0 token in map form.
4249
*

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OAuth2IntrospectionAuthenticationProvider.java

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,25 @@
1515
*/
1616
package org.springframework.security.oauth2.server.resource.authentication;
1717

18-
import java.time.Instant;
1918
import java.util.Collection;
20-
import java.util.Collections;
2119
import java.util.Map;
22-
import java.util.Optional;
23-
import java.util.stream.Collectors;
2420

21+
import org.springframework.core.convert.converter.Converter;
2522
import org.springframework.http.HttpStatus;
2623
import org.springframework.security.authentication.AbstractAuthenticationToken;
2724
import org.springframework.security.authentication.AuthenticationProvider;
2825
import org.springframework.security.core.Authentication;
2926
import org.springframework.security.core.AuthenticationException;
3027
import org.springframework.security.core.GrantedAuthority;
31-
import org.springframework.security.core.authority.SimpleGrantedAuthority;
32-
import org.springframework.security.oauth2.core.OAuth2AccessToken;
3328
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
3429
import org.springframework.security.oauth2.core.OAuth2Error;
3530
import org.springframework.security.oauth2.core.OAuth2TokenAttributes;
36-
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
37-
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient;
3831
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
3932
import org.springframework.security.oauth2.server.resource.BearerTokenError;
33+
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
34+
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient;
4035
import org.springframework.util.Assert;
4136

42-
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.EXPIRES_AT;
43-
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.ISSUED_AT;
44-
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SCOPE;
45-
4637
/**
4738
* An {@link AuthenticationProvider} implementation for opaque
4839
* <a href="https://tools.ietf.org/html/rfc6750#section-1.2" target="_blank">Bearer Token</a>s,
@@ -70,6 +61,8 @@ public final class OAuth2IntrospectionAuthenticationProvider implements Authenti
7061
invalidToken("An error occurred while attempting to introspect the token: Invalid token");
7162

7263
private OAuth2TokenIntrospectionClient introspectionClient;
64+
private Converter<OAuth2TokenAttributes, ? extends AbstractAuthenticationToken> tokenAttributesAuthenticationConverter =
65+
new OAuth2TokenAttributesAuthenticationConverter();
7366

7467
/**
7568
* Creates a {@code OAuth2IntrospectionAuthenticationProvider} with the provided parameters
@@ -110,6 +103,11 @@ public Authentication authenticate(Authentication authentication) throws Authent
110103
return result;
111104
}
112105

106+
public void setTokenAttributesAuthenticationConverter
107+
(Converter<OAuth2TokenAttributes, ? extends AbstractAuthenticationToken> tokenAttributesAuthenticationConverter) {
108+
this.tokenAttributesAuthenticationConverter = tokenAttributesAuthenticationConverter;
109+
}
110+
113111
/**
114112
* {@inheritDoc}
115113
*/
@@ -119,20 +117,7 @@ public boolean supports(Class<?> authentication) {
119117
}
120118

121119
private AbstractAuthenticationToken convert(String token, Map<String, Object> claims) {
122-
Instant iat = (Instant) claims.get(ISSUED_AT);
123-
Instant exp = (Instant) claims.get(EXPIRES_AT);
124-
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
125-
token, iat, exp);
126-
Collection<GrantedAuthority> authorities = extractAuthorities(claims);
127-
return new OAuth2IntrospectionAuthenticationToken(accessToken, new OAuth2TokenAttributes(claims), authorities);
128-
}
129-
130-
private Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) {
131-
Collection<String> scopes = (Collection<String>) claims.get(SCOPE);
132-
return Optional.ofNullable(scopes).orElse(Collections.emptyList())
133-
.stream()
134-
.map(authority -> new SimpleGrantedAuthority("SCOPE_" + authority))
135-
.collect(Collectors.toList());
120+
return this.tokenAttributesAuthenticationConverter.convert(new OAuth2TokenAttributes(token, claims));
136121
}
137122

138123
private static BearerTokenError invalidToken(String message) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2002-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.oauth2.server.resource.authentication;
18+
19+
import java.time.Instant;
20+
import java.util.Collection;
21+
import java.util.Collections;
22+
import java.util.Optional;
23+
import java.util.stream.Collectors;
24+
25+
import org.springframework.core.convert.converter.Converter;
26+
import org.springframework.security.authentication.AbstractAuthenticationToken;
27+
import org.springframework.security.core.GrantedAuthority;
28+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
29+
import org.springframework.security.oauth2.core.OAuth2AccessToken;
30+
import org.springframework.security.oauth2.core.OAuth2TokenAttributes;
31+
32+
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.EXPIRES_AT;
33+
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.ISSUED_AT;
34+
35+
public class OAuth2TokenAttributesAuthenticationConverter
36+
implements Converter<OAuth2TokenAttributes, AbstractAuthenticationToken> {
37+
38+
private static final String SCOPE = "scope";
39+
40+
@Override
41+
public AbstractAuthenticationToken convert(OAuth2TokenAttributes source) {
42+
Instant iat = source.getAttribute(ISSUED_AT);
43+
Instant exp = source.getAttribute(EXPIRES_AT);
44+
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, source.getToken(), iat, exp);
45+
Collection<GrantedAuthority> authorities = extractAuthorities(source);
46+
return new OAuth2IntrospectionAuthenticationToken(accessToken, source, authorities);
47+
}
48+
49+
private Collection<GrantedAuthority> extractAuthorities(OAuth2TokenAttributes attributes) {
50+
Collection<String> scopes = attributes.getAttribute(SCOPE);
51+
return Optional.ofNullable(scopes).orElse(Collections.emptyList())
52+
.stream()
53+
.map(authority -> new SimpleGrantedAuthority("SCOPE_" + authority))
54+
.collect(Collectors.toList());
55+
}
56+
}

0 commit comments

Comments
 (0)