This commit is contained in:
Andrey Litvitski 2025-06-30 11:01:52 +09:00 committed by GitHub
commit e06386030c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2025 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.
@ -21,6 +21,7 @@ import java.util.Collection;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimNames; import org.springframework.security.oauth2.jwt.JwtClaimNames;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -30,10 +31,12 @@ import org.springframework.util.Assert;
* @author Josh Cummings * @author Josh Cummings
* @author Evgeniy Cheban * @author Evgeniy Cheban
* @author Olivier Antoine * @author Olivier Antoine
* @author Andrey Litvitski
* @since 5.1 * @since 5.1
*/ */
public class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> { public class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
private Converter<Jwt, OAuth2AuthenticatedPrincipal> jwtPrincipalConverter;
private Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); private Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
private String principalClaimName = JwtClaimNames.SUB; private String principalClaimName = JwtClaimNames.SUB;
@ -42,8 +45,26 @@ public class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthen
public final AbstractAuthenticationToken convert(Jwt jwt) { public final AbstractAuthenticationToken convert(Jwt jwt) {
Collection<GrantedAuthority> authorities = this.jwtGrantedAuthoritiesConverter.convert(jwt); Collection<GrantedAuthority> authorities = this.jwtGrantedAuthoritiesConverter.convert(jwt);
if (this.jwtPrincipalConverter == null) {
String principalClaimValue = jwt.getClaimAsString(this.principalClaimName); String principalClaimValue = jwt.getClaimAsString(this.principalClaimName);
return new JwtAuthenticationToken(jwt, authorities, principalClaimValue); return new JwtAuthenticationToken(jwt, authorities, principalClaimValue);
} else {
OAuth2AuthenticatedPrincipal principal = this.jwtPrincipalConverter.convert(jwt);
authorities.addAll(principal.getAuthorities());
return new JwtAuthenticationToken(jwt, principal, authorities);
}
}
/**
* Sets the {@link Converter Converter&lt;Jwt, Collection&lt;OAuth2AuthenticatedPrincipal&gt;&gt;}
* to use.
* @param jwtPrincipalConverter The converter
* @since 6.5.0
*/
public void setJwtPrincipalConverter(
Converter<Jwt, OAuth2AuthenticatedPrincipal> jwtPrincipalConverter) {
Assert.notNull(jwtPrincipalConverter, "jwtPrincipalConverter cannot be null");
this.jwtPrincipalConverter = jwtPrincipalConverter;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2025 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.
@ -19,6 +19,7 @@ package org.springframework.security.oauth2.server.resource.authentication;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import org.springframework.security.core.AuthenticatedPrincipal;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.Transient; import org.springframework.security.core.Transient;
@ -29,6 +30,7 @@ import org.springframework.security.oauth2.jwt.Jwt;
* {@link Jwt} {@code Authentication}. * {@link Jwt} {@code Authentication}.
* *
* @author Joe Grandja * @author Joe Grandja
* @author Andrey Litvitski
* @since 5.1 * @since 5.1
* @see AbstractOAuth2TokenAuthenticationToken * @see AbstractOAuth2TokenAuthenticationToken
* @see Jwt * @see Jwt
@ -72,6 +74,22 @@ public class JwtAuthenticationToken extends AbstractOAuth2TokenAuthenticationTok
this.name = name; this.name = name;
} }
/**
* Constructs a {@code JwtAuthenticationToken} using the provided parameters.
* @param jwt the JWT
* @param principal the principal
* @param authorities the authorities assigned to the JWT
*/
public JwtAuthenticationToken(Jwt jwt, Object principal, Collection<? extends GrantedAuthority> authorities) {
super(jwt, principal, jwt, authorities);
this.setAuthenticated(true);
if (principal instanceof AuthenticatedPrincipal) {
this.name = ((AuthenticatedPrincipal) principal).getName();
} else {
this.name = jwt.getSubject();
}
}
@Override @Override
public Map<String, Object> getTokenAttributes() { public Map<String, Object> getTokenAttributes() {
return this.getToken().getClaims(); return this.getToken().getClaims();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2025 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.
@ -26,6 +26,7 @@ import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrinci
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.util.Assert;
/** /**
* A {@link Converter} that takes a {@link Jwt} and converts it into a * A {@link Converter} that takes a {@link Jwt} and converts it into a
@ -41,6 +42,7 @@ import org.springframework.security.oauth2.jwt.Jwt;
* {@link BearerTokenAuthentication}. * {@link BearerTokenAuthentication}.
* *
* @author Josh Cummings * @author Josh Cummings
* @author Andrey Litvitski
* @since 5.2 * @since 5.2
*/ */
public final class JwtBearerTokenAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> { public final class JwtBearerTokenAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {
@ -58,4 +60,16 @@ public final class JwtBearerTokenAuthenticationConverter implements Converter<Jw
return new BearerTokenAuthentication(principal, accessToken, authorities); return new BearerTokenAuthentication(principal, accessToken, authorities);
} }
/**
* Sets the {@link Converter Converter&lt;Jwt, Collection&lt;OAuth2AuthenticatedPrincipal&gt;&gt;}
* to use.
* @param jwtPrincipalConverter The converter
* @since 6.5.0
*/
public void setJwtPrincipalConverter(
Converter<Jwt, OAuth2AuthenticatedPrincipal> jwtPrincipalConverter) {
Assert.notNull(jwtPrincipalConverter, "jwtPrincipalConverter cannot be null");
this.jwtAuthenticationConverter.setJwtPrincipalConverter(jwtPrincipalConverter);
}
} }