2 changed files with 210 additions and 0 deletions
@ -0,0 +1,67 @@
@@ -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 @@
@@ -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…
Reference in new issue