gpt4 book ai didi

java - 尽管在 Spring security 中使用自定义用户详细信息类,但主体仍然是字符串

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:07:14 26 4
gpt4 key购买 nike

我有一个自定义的 UserDetailsS​​ervice 如下:

@Service
public class AuthenticatedUserService implements UserDetailsService {

private final UserRepository userRepository;

@Autowired
public AuthenticatedUserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public UserDetails loadUserByUsername(String username) {
UserCredentials userCredentials = userRepository.findByUsername(username);
if (userCredentials == null) {
throw new UsernameNotFoundException("The user " + username + " does not exist");
}
return new AuthenticatedPrincipal(userCredentials);
}
}

我的 AuthenticatedPrincipal 看起来像这样:

public class AuthenticatedPrincipal implements UserDetails {
private UserCredentials userCredentials;

public AuthenticatedPrincipal() {

}

public AuthenticatedPrincipal(UserCredentials userCredentials) {
this.userCredentials = userCredentials;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
...
return authorities;
}

@Override
public String getPassword() {
return userCredentials.getPassword();
}

@Override
public String getUsername() {
return userCredentials.getUsername();
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
}

我以这种方式使用我的服务:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Qualifier("authenticatedUserService")
@Autowired
private UserDetailsService userDetailsService;

@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// auth.ldapAuthentication()

auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}

...
}

一切正常。我可以登录就好了。但是我从来没有得到我的自定义委托(delegate)人。在每个地方,只需获取一个包含用户名的普通字符串。例如,我想实现一个自定义的 SecurityExpressionRoot

public class CustomMethodSecurityExpressionRoot
extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

public CustomMethodSecurityExpressionRoot(Authentication authentication) {
super(authentication);
}

public boolean isMember(Long OrganizationId) {
// Throws an exception, because principal is just a string
AuthenticatedPrincipal user = (AuthenticatedPrincipal) this.getPrincipal();
return false;
}

当我尝试将它插入我的一个 Controller 时,也会发生同样的情况。

public ResponseEntity listMessages(@AuthenticationPrincipal Principal principal) {

我不知道该怎么做,再试一次。我看不出我所做的和 this tutorial 有什么不同, 例如。

最佳答案

好的,我已经设法找到并解决了我的问题。我正在使用 JWT 并使用自定义过滤器来设置身份验证。我没有返回正确的 Authentication 对象,而是使用默认的 UsernamePasswordAuthenticationToken。为了解决这个问题,我继续创建了自己的 token 类:

public class TokenBasedAuthentication extends AbstractAuthenticationToken {
private final UserDetails principal;

public TokenBasedAuthentication(AuthenticatedPrincipal principal) {
super(principal.getAuthorities());
this.principal = principal;
}

@Override
public boolean isAuthenticated() {
return true;
}

@Override
public UserDetails getPrincipal() {
return principal;
}
}

然后,在我的过滤器中,我继续创建了一个适当的身份验证对象:

AuthenticatedPrincipal userDetails = (AuthenticatedPrincipal) userDetailsService.loadUserByUsername(username);
TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
SecurityContextHolder.getContext().setAuthentication(authentication);

现在我也找到了合适的校长。实际上应该早点弄清楚,但我想还好吧。

关于java - 尽管在 Spring security 中使用自定义用户详细信息类,但主体仍然是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53175208/

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