mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Add BearerTokenAuthentication
Fixes gh-7343
This commit is contained in:
		
							parent
							
								
									346b8c2cff
								
							
						
					
					
						commit
						c019507770
					
				| @ -0,0 +1,67 @@ | ||||
| /* | ||||
|  * Copyright 2002-2019 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| package org.springframework.security.oauth2.server.resource.authentication; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.springframework.security.core.GrantedAuthority; | ||||
| import org.springframework.security.core.SpringSecurityCoreVersion; | ||||
| import org.springframework.security.core.Transient; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| /** | ||||
|  * An {@link org.springframework.security.core.Authentication} token that represents a successful authentication as | ||||
|  * obtained through a bearer token. | ||||
|  * | ||||
|  * @author Josh Cummings | ||||
|  * @since 5.2 | ||||
|  */ | ||||
| @Transient | ||||
| public class BearerTokenAuthentication extends AbstractOAuth2TokenAuthenticationToken<OAuth2AccessToken> { | ||||
| 
 | ||||
| 	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; | ||||
| 
 | ||||
| 	private Map<String, Object> attributes; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Constructs a {@link BearerTokenAuthentication} with the provided arguments | ||||
| 	 * | ||||
| 	 * @param principal The OAuth 2.0 attributes | ||||
| 	 * @param credentials The verified token | ||||
| 	 * @param authorities The authorities associated with the given token | ||||
| 	 */ | ||||
| 	public BearerTokenAuthentication(OAuth2AuthenticatedPrincipal principal, OAuth2AccessToken credentials, | ||||
| 			Collection<? extends GrantedAuthority> authorities) { | ||||
| 
 | ||||
| 		super(credentials, principal, credentials, authorities); | ||||
| 		Assert.isTrue(credentials.getTokenType() == OAuth2AccessToken.TokenType.BEARER, "credentials must be a bearer token"); | ||||
| 		this.attributes = Collections.unmodifiableMap(new LinkedHashMap<>(principal.getAttributes())); | ||||
| 		setAuthenticated(true); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * {@inheritDoc} | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Map<String, Object> getTokenAttributes() { | ||||
| 		return this.attributes; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,143 @@ | ||||
| /* | ||||
|  * Copyright 2002-2019 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.springframework.security.oauth2.server.resource.authentication; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.time.Instant; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import net.minidev.json.JSONObject; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import org.springframework.security.core.GrantedAuthority; | ||||
| import org.springframework.security.core.authority.AuthorityUtils; | ||||
| import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.assertj.core.api.Assertions.assertThatCode; | ||||
| import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.CLIENT_ID; | ||||
| import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SUBJECT; | ||||
| import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.USERNAME; | ||||
| 
 | ||||
| /** | ||||
|  * Tests for {@link BearerTokenAuthentication} | ||||
|  * | ||||
|  * @author Josh Cummings | ||||
|  */ | ||||
| public class BearerTokenAuthenticationTests { | ||||
| 	private final OAuth2AccessToken token = | ||||
| 			new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, | ||||
| 				"token", Instant.now(), Instant.now().plusSeconds(3600)); | ||||
| 	private final String name = "sub"; | ||||
| 	private Map<String, Object> attributesMap = new HashMap<>(); | ||||
| 	private DefaultOAuth2AuthenticatedPrincipal principal; | ||||
| 	private final Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("USER"); | ||||
| 
 | ||||
| 	@Before | ||||
| 	public void setUp() { | ||||
| 		this.attributesMap.put(SUBJECT, this.name); | ||||
| 		this.attributesMap.put(CLIENT_ID, "client_id"); | ||||
| 		this.attributesMap.put(USERNAME, "username"); | ||||
| 		this.principal = new DefaultOAuth2AuthenticatedPrincipal(this.attributesMap, null); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getNameWhenConfiguredInConstructorThenReturnsName() { | ||||
| 		OAuth2AuthenticatedPrincipal principal = new DefaultOAuth2AuthenticatedPrincipal(this.name, this.attributesMap, this.authorities); | ||||
| 		BearerTokenAuthentication authenticated = new BearerTokenAuthentication(principal, this.token, this.authorities); | ||||
| 		assertThat(authenticated.getName()).isEqualTo(this.name); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getNameWhenHasNoSubjectThenReturnsNull() { | ||||
| 		OAuth2AuthenticatedPrincipal principal = | ||||
| 				new DefaultOAuth2AuthenticatedPrincipal(Collections.singletonMap("claim", "value"), null); | ||||
| 		BearerTokenAuthentication authenticated = new BearerTokenAuthentication(principal, this.token, null); | ||||
| 		assertThat(authenticated.getName()).isNull(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getNameWhenTokenHasUsernameThenReturnsUsernameAttribute() { | ||||
| 		BearerTokenAuthentication authenticated = new BearerTokenAuthentication(this.principal, this.token, null); | ||||
| 		assertThat(authenticated.getName()).isEqualTo(this.principal.getAttribute(SUBJECT)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void constructorWhenTokenIsNullThenThrowsException() { | ||||
| 		assertThatCode(() -> new BearerTokenAuthentication(this.principal, null, null)) | ||||
| 				.isInstanceOf(IllegalArgumentException.class) | ||||
| 				.hasMessageContaining("token cannot be null"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void constructorWhenCredentialIsNullThenThrowsException() { | ||||
| 		assertThatCode(() -> new BearerTokenAuthentication(null, this.token, null)) | ||||
| 				.isInstanceOf(IllegalArgumentException.class) | ||||
| 				.hasMessageContaining("principal cannot be null"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void constructorWhenPassingAllAttributesThenTokenIsAuthenticated() { | ||||
| 		OAuth2AuthenticatedPrincipal principal = | ||||
| 				new DefaultOAuth2AuthenticatedPrincipal("harris", Collections.singletonMap("claim", "value"), null); | ||||
| 		BearerTokenAuthentication authenticated = new BearerTokenAuthentication(principal, this.token, null); | ||||
| 		assertThat(authenticated.isAuthenticated()).isTrue(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getTokenAttributesWhenHasTokenThenReturnsThem() { | ||||
| 		BearerTokenAuthentication authenticated = | ||||
| 				new BearerTokenAuthentication(this.principal, this.token, Collections.emptyList()); | ||||
| 		assertThat(authenticated.getTokenAttributes()).isEqualTo(this.principal.getAttributes()); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void getAuthoritiesWhenHasAuthoritiesThenReturnsThem() { | ||||
| 		List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("USER"); | ||||
| 		BearerTokenAuthentication authenticated = | ||||
| 				new BearerTokenAuthentication(this.principal, this.token, authorities); | ||||
| 		assertThat(authenticated.getAuthorities()).isEqualTo(authorities); | ||||
| 	} | ||||
| 
 | ||||
| 	// gh-6843 | ||||
| 	@Test | ||||
| 	public void constructorWhenDefaultParametersThenSetsPrincipalToAttributesCopy() { | ||||
| 		JSONObject attributes = new JSONObject(); | ||||
| 		attributes.put("active", true); | ||||
| 		OAuth2AuthenticatedPrincipal principal = new DefaultOAuth2AuthenticatedPrincipal(attributes, null); | ||||
| 		BearerTokenAuthentication token = new BearerTokenAuthentication(principal, this.token, null); | ||||
| 		assertThat(token.getPrincipal()).isNotSameAs(attributes); | ||||
| 		assertThat(token.getTokenAttributes()).isNotSameAs(attributes); | ||||
| 	} | ||||
| 
 | ||||
| 	// gh-6843 | ||||
| 	@Test | ||||
| 	public void toStringWhenAttributesContainsURLThenDoesNotFail() throws Exception { | ||||
| 		JSONObject attributes = new JSONObject(Collections.singletonMap("iss", new URL("https://idp.example.com"))); | ||||
| 		OAuth2AuthenticatedPrincipal principal = new DefaultOAuth2AuthenticatedPrincipal(attributes, null); | ||||
| 		BearerTokenAuthentication token = new BearerTokenAuthentication(principal, this.token, null); | ||||
| 		assertThatCode(token::toString) | ||||
| 				.doesNotThrowAnyException(); | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user