gpt4 book ai didi

Spring Security 不返回 UserDetails 对象,只返回用户名

转载 作者:行者123 更新时间:2023-12-01 01:24:54 25 4
gpt4 key购买 nike

我原以为我的授权实现已完成,但在尝试检索 UserDetails 对象时,我得到的只是用户名。

我正在使用具有以下细节的 oauth。

配置 AuthenticationManager:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}

完成后,我可以调试我的 userDetailsS​​ervice:

@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
MyUser persistedUser = userRepository.findByEmail(email);

if (persistedUser == null) {
throw new UsernameNotFoundException(String.format("The email %s doesn't exist", email));
}

List<GrantedAuthority> authorities = new ArrayList<>();

MyUser inMemoryUser = new MyUser(persistedUser.getEmail(), null, persistedUser.getEnabled(), false,
false, false, authorities);

return inMemoryUser;
}
}

这一切都很好,我的客户取回了 JWT。但是在调试后面的controller方法的时候发现了如下问题。

@GetMapping
public @ResponseBody Iterable<Curriculum> getMyCurriculums(@AuthenticationPrincipal MyUser injectedUser) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
MyUser principle = (MyUser) auth.getPrincipal();
return curriculumService.findByUser(principle);
}

在这种情况下,injectedUser = null,auth 是一个 OAuth2Authentication,而 principle 是一个 String - 用户名。应该是我的用户

最佳答案

您应该配置 Spring Security 以将 jwt token 解码为 MyUser 对象。

首先定义一个自定义的OAuth2Authentication来封装MyUser

public class OAuth2AuthenticationUser extends OAuth2Authentication {

private MyUser myUser;

public OAuth2AuthenticationUser(OAuth2Request storedRequest, Authentication userAuthentication) {
super(storedRequest, userAuthentication);
}

public MyUser getMyUser() {
return myUser;
}

public void setMyUser(MyUser) {
this.myUser= myUser;
}
}

然后在一个Security Configuration类中配置jwt token解码如下:

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("SIGNING_KEY");
converter.setAccessTokenConverter(getAuthenticationAccessTokenConverter());
return converter;
}

private DefaultAccessTokenConverter getAuthenticationAccessTokenConverter() {
return new DefaultAccessTokenConverter() {
@Override
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
OAuth2Authentication authentication = (OAuth2Authentication) super.extractAuthentication(map);

OAuth2AuthenticationUser authenticationUser =
new OAuth2AuthenticationUser(authentication.getOAuth2Request(), authentication.getUserAuthentication());

MyUser myUser = new MyUser();

// Example properties
myUser.setId(map.get("id") != null ? Long.valueOf(map.get("id").toString()) : null);
myUser.setUsername(map.get("user_name") != null ? map.get("user_name").toString() : null);
myUser.setFullName(map.get("fullName") != null ? map.get("fullName").toString() : null);
myUser.setCustomerId(map.get("customerId") != null ? Long.valueOf(map.get("customerId").toString()) : null);
myUser.setCustomerName(map.get("customerName") != null ? map.get("customerName").toString() : null);

// More other properties

authenticationUser.setMyUser(myUser);

return authenticationUser;
}
};
}

然后您可以从 Spring Security 上下文访问 MyUser 对象,如下所示:

private static MyUser getMyUser() {
OAuth2AuthenticationUser authentication = (OAuth2AuthenticationUser) SecurityContextHolder.getContext().getAuthentication();
return (authentication != null && authentication.getMyUser() != null ? authentication.getMyUser() : new MyUser());
}

这非常适合无状态环境,因为对用户详细信息的数据库访问被最小化,您只需要 jwt token 。

关于Spring Security 不返回 UserDetails 对象,只返回用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47805115/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com