我需要将经过身份验证的用户的firstName和id存储在我的访问令牌中,但在调用该属性时,数据返回为空。
请注意,我首先添加声明。
public OAuth2TokenCustomizer<JwtEncodingContext> tokenCustomizer() {
return context -> {
OAuth2ClientAuthenticationToken principal = context.getPrincipal();
CustomUserAuthorities user = (CustomUserAuthorities) principal.getDetails();
List<String> authorities = user.getAuthorities().stream().map(x -> x.getAuthority()).toList();
if (context.getTokenType().getValue().equals("access_token")) {
// @formatter:off
context.getClaims()
.claim("firstName", user.getFirstName())
.claim("authorities", authorities)
.claim("username", user.getUsername())
.claim("firstName", user.getFirstName())
;
// @formatter:on
}
};
}
我正在调用一个具有自定义属性的单独的CustomUserAuthorities类。
public class CustomUserAuthorities {
private String username;
private String firstName;
private Collection<? extends GrantedAuthority> authorities;
public CustomUserAuthorities(String firstName, String username, Collection<? extends GrantedAuthority> authorities) {
this.username = username;
this.authorities = authorities;
this.firstName = firstName;
}
public String getUsername() {
return username;
}
public String getFirstName() {
return firstName;
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
}
在CustomPasswordAuthenticationProvider类中,我调用了firstName,并通过调用oAuth2ClientAuthenticationToken.getDetails将其实例化。
public class CustomPasswordAuthenticationProvider implements AuthenticationProvider {
private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2";
private final OAuth2AuthorizationService authorizationService;
private final UserDetailsService userDetailsService;
private final OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator;
private final PasswordEncoder passwordEncoder;
private String firstName = "";
private String username = "";
private String password = "";
private Set<String> authorizedScopes = new HashSet<>();
public CustomPasswordAuthenticationProvider(OAuth2AuthorizationService authorizationService,
OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator,
UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
Assert.notNull(authorizationService, "authorizationService cannot be null");
Assert.notNull(tokenGenerator, "TokenGenerator cannot be null");
Assert.notNull(userDetailsService, "UserDetailsService cannot be null");
Assert.notNull(passwordEncoder, "PasswordEncoder cannot be null");
this.authorizationService = authorizationService;
this.tokenGenerator = tokenGenerator;
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
CustomPasswordAuthenticationToken customPasswordAuthenticationToken = (CustomPasswordAuthenticationToken) authentication;
OAuth2ClientAuthenticationToken clientPrincipal = getAuthenticatedClientElseThrowInvalidClient(customPasswordAuthenticationToken);
RegisteredClient registeredClient = clientPrincipal.getRegisteredClient();
username = customPasswordAuthenticationToken.getUsername();
password = customPasswordAuthenticationToken.getPassword();
UserDetails user = null;
try {
user = userDetailsService.loadUserByUsername(username);
} catch (UsernameNotFoundException e) {
throw new OAuth2AuthenticationException("Invalid credentials");
}
if (!passwordEncoder.matches(password, user.getPassword()) || !user.getUsername().equals(username)) {
throw new OAuth2AuthenticationException("Invalid credentials");
}
authorizedScopes = user.getAuthorities().stream()
.map(scope -> scope.getAuthority())
.filter(scope -> registeredClient.getScopes().contains(scope))
.collect(Collectors.toSet());
//-----------Create a new Security Context Holder Context----------
OAuth2ClientAuthenticationToken oAuth2ClientAuthenticationToken = (OAuth2ClientAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
CustomUserAuthorities customPasswordUser = new CustomUserAuthorities(firstName, username, user.getAuthorities());
oAuth2ClientAuthenticationToken.setDetails(customPasswordUser);
var newcontext = SecurityContextHolder.createEmptyContext();
newcontext.setAuthentication(oAuth2ClientAuthenticationToken);
SecurityContextHolder.setContext(newcontext);
我期望返回firstName:经过身份验证的用户的名字。但它返回了“”。空的
{
"sub": "myclientid",
"aud": "myclientid",
"firstName": "",
"nbf": 1691786519,
"iss": "http://localhost:8080",
"exp": 1692650519,
"iat": 1691786519,
"authorities": [
"ROLE_CLIENT"
],
"username": "[email protected]"
}