소스 검색

Added setPrincipalClaimName to JwtAuthenticationConverter

Fixes gh-8186
Evgeniy Cheban 5 년 전
부모
커밋
25fb1f417d

+ 22 - 1
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationConverter.java

@@ -22,21 +22,30 @@ import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.jwt.JwtClaimNames;
 import org.springframework.util.Assert;
 
 /**
  * @author Rob Winch
  * @author Josh Cummings
+ * @author Evgeniy Cheban
  * @since 5.1
  */
 public class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
 	private Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter
 			= new JwtGrantedAuthoritiesConverter();
 
+	private String principalClaimName;
+
 	@Override
 	public final AbstractAuthenticationToken convert(Jwt jwt) {
 		Collection<GrantedAuthority> authorities = extractAuthorities(jwt);
-		return new JwtAuthenticationToken(jwt, authorities);
+		if (this.principalClaimName == null) {
+			return new JwtAuthenticationToken(jwt, authorities);
+		}
+
+		String name = jwt.getClaim(this.principalClaimName);
+		return new JwtAuthenticationToken(jwt, authorities, name);
 	}
 
 	/**
@@ -65,4 +74,16 @@ public class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthen
 		Assert.notNull(jwtGrantedAuthoritiesConverter, "jwtGrantedAuthoritiesConverter cannot be null");
 		this.jwtGrantedAuthoritiesConverter = jwtGrantedAuthoritiesConverter;
 	}
+
+	/**
+	 * Sets the principal claim name.
+	 * Defaults to {@link JwtClaimNames#SUB}.
+	 *
+	 * @param principalClaimName The principal claim name
+	 * @since 5.4
+	 */
+	public void setPrincipalClaimName(String principalClaimName) {
+		Assert.hasText(principalClaimName, "principalClaimName cannot be empty");
+		this.principalClaimName = principalClaimName;
+	}
 }

+ 32 - 0
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationConverterTests.java

@@ -35,6 +35,7 @@ import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
  * Tests for {@link JwtAuthenticationConverter}
  *
  * @author Josh Cummings
+ * @author Evgeniy Cheban
  */
 public class JwtAuthenticationConverterTests {
 	JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
@@ -73,4 +74,35 @@ public class JwtAuthenticationConverterTests {
 		assertThat(authorities).containsExactly(
 				new SimpleGrantedAuthority("blah"));
 	}
+
+	@Test
+	public void whenSettingNullPrincipalClaimName() {
+		assertThatIllegalArgumentException()
+				.isThrownBy(() -> this.jwtAuthenticationConverter.setPrincipalClaimName(null))
+				.withMessage("principalClaimName cannot be empty");
+	}
+
+	@Test
+	public void whenSettingEmptyPrincipalClaimName() {
+		assertThatIllegalArgumentException()
+				.isThrownBy(() -> this.jwtAuthenticationConverter.setPrincipalClaimName(""))
+				.withMessage("principalClaimName cannot be empty");
+	}
+
+	@Test
+	public void whenSettingBlankPrincipalClaimName() {
+		assertThatIllegalArgumentException()
+				.isThrownBy(() -> this.jwtAuthenticationConverter.setPrincipalClaimName(" "))
+				.withMessage("principalClaimName cannot be empty");
+	}
+
+	@Test
+	public void convertWhenPrincipalClaimNameSet() {
+		this.jwtAuthenticationConverter.setPrincipalClaimName("user_id");
+
+		Jwt jwt = jwt().claim("user_id", "100").build();
+		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt);
+
+		assertThat(authentication.getName()).isEqualTo("100");
+	}
 }