Skip to content

Commit

Permalink
Allow authentication details to be set by converter
Browse files Browse the repository at this point in the history
Prevent JwtAuthenticationProvider from setting authentication details
when jwtAuthenticationConverter returned an authentication instance
with non null details.

Closes gh-11822
  • Loading branch information
ch4mpy authored and sjohnr committed Dec 13, 2022
1 parent c2d0ea3 commit 7ad4ebd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -56,6 +56,7 @@
*
* @author Josh Cummings
* @author Joe Grandja
* @author Jerome Wacongne ch4mp@c4-soft.com
* @since 5.1
* @see AuthenticationProvider
* @see JwtDecoder
Expand Down Expand Up @@ -86,7 +87,9 @@ public Authentication authenticate(Authentication authentication) throws Authent
BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication;
Jwt jwt = getJwt(bearer);
AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
token.setDetails(bearer.getDetails());
if (token.getDetails() == null) {
token.setDetails(bearer.getDetails());
}
this.logger.debug("Authenticated token");
return token;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.BadJwtException;
Expand All @@ -43,12 +44,13 @@
* Tests for {@link JwtAuthenticationProvider}
*
* @author Josh Cummings
* @author Jerome Wacongne ch4mp@c4-soft.com
*/
@ExtendWith(MockitoExtension.class)
public class JwtAuthenticationProviderTests {

@Mock
Converter<Jwt, JwtAuthenticationToken> jwtAuthenticationConverter;
Converter<Jwt, AbstractAuthenticationToken> jwtAuthenticationConverter;

@Mock
JwtDecoder jwtDecoder;
Expand Down Expand Up @@ -107,17 +109,46 @@ public void authenticateWhenDecoderFailsGenericallyThenThrowsGenericException()

@Test
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();
Object details = mock(Object.class);
token.setDetails(details);
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);
// @formatter:off
assertThat(this.provider.authenticate(token))
.isEqualTo(authentication).hasFieldOrPropertyWithValue("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",
details);
expectedDetails);
// @formatter:on
}

Expand Down

0 comments on commit 7ad4ebd

Please sign in to comment.