1
0
mirror of synced 2026-05-22 13:23:17 +00:00

Allow authentication details to be set by converter

Prevent JwtAuthenticationProvider from setting authentication details
when jwtAuthenticationConverter returned an authentication instance
with non null details.

Closes gh-11822
This commit is contained in:
ch4mpy
2022-09-26 09:30:03 -10:00
committed by Steve Riesenberg
parent c2d0ea3694
commit 7ad4ebd07a
2 changed files with 39 additions and 5 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -56,6 +56,7 @@ import org.springframework.util.Assert;
* *
* @author Josh Cummings * @author Josh Cummings
* @author Joe Grandja * @author Joe Grandja
* @author Jerome Wacongne ch4mp@c4-soft.com
* @since 5.1 * @since 5.1
* @see AuthenticationProvider * @see AuthenticationProvider
* @see JwtDecoder * @see JwtDecoder
@@ -86,7 +87,9 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication; BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication;
Jwt jwt = getJwt(bearer); Jwt jwt = getJwt(bearer);
AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt); AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
token.setDetails(bearer.getDetails()); if (token.getDetails() == null) {
token.setDetails(bearer.getDetails());
}
this.logger.debug("Authenticated token"); this.logger.debug("Authenticated token");
return token; return token;
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.BadJwtException; import org.springframework.security.oauth2.jwt.BadJwtException;
@@ -43,12 +44,13 @@ import static org.mockito.Mockito.mock;
* Tests for {@link JwtAuthenticationProvider} * Tests for {@link JwtAuthenticationProvider}
* *
* @author Josh Cummings * @author Josh Cummings
* @author Jerome Wacongne ch4mp@c4-soft.com
*/ */
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class JwtAuthenticationProviderTests { public class JwtAuthenticationProviderTests {
@Mock @Mock
Converter<Jwt, JwtAuthenticationToken> jwtAuthenticationConverter; Converter<Jwt, AbstractAuthenticationToken> jwtAuthenticationConverter;
@Mock @Mock
JwtDecoder jwtDecoder; JwtDecoder jwtDecoder;
@@ -107,6 +109,17 @@ public class JwtAuthenticationProviderTests {
@Test @Test
public void authenticateWhenConverterReturnsAuthenticationThenProviderPropagatesIt() { public void authenticateWhenConverterReturnsAuthenticationThenProviderPropagatesIt() {
BearerTokenAuthenticationToken token = this.authentication();
Jwt jwt = TestJwts.jwt().build();
JwtAuthenticationToken authentication = new JwtAuthenticationToken(jwt);
given(this.jwtDecoder.decode(token.getToken())).willReturn(jwt);
given(this.jwtAuthenticationConverter.convert(jwt)).willReturn(authentication);
assertThat(this.provider.authenticate(token)).isEqualTo(authentication);
}
@Test
public void authenticateWhenConverterDoesNotSetAuthenticationDetailsThenProviderSetsItWithTokenDetails() {
BearerTokenAuthenticationToken token = this.authentication(); BearerTokenAuthenticationToken token = this.authentication();
Object details = mock(Object.class); Object details = mock(Object.class);
token.setDetails(details); token.setDetails(details);
@@ -117,7 +130,25 @@ public class JwtAuthenticationProviderTests {
// @formatter:off // @formatter:off
assertThat(this.provider.authenticate(token)) assertThat(this.provider.authenticate(token))
.isEqualTo(authentication).hasFieldOrPropertyWithValue("details", .isEqualTo(authentication).hasFieldOrPropertyWithValue("details",
details); details);
// @formatter:on
}
@Test
public void authenticateWhenConverterSetsAuthenticationDetailsThenProviderDoesNotOverwriteIt() {
BearerTokenAuthenticationToken token = this.authentication();
Object details = mock(Object.class);
token.setDetails(details);
Jwt jwt = TestJwts.jwt().build();
JwtAuthenticationToken authentication = new JwtAuthenticationToken(jwt);
Object expectedDetails = "To be kept as is";
authentication.setDetails(expectedDetails);
given(this.jwtDecoder.decode(token.getToken())).willReturn(jwt);
given(this.jwtAuthenticationConverter.convert(jwt)).willReturn(authentication);
// @formatter:off
assertThat(this.provider.authenticate(token))
.isEqualTo(authentication).hasFieldOrPropertyWithValue("details",
expectedDetails);
// @formatter:on // @formatter:on
} }