我的目标是从 Principal
.
注意:默认情况下,springsecurity没有在主体中存储密码。我重写 UserDetailsService
添加更多信息,如 name
, id
, channelIds
. 但是,我的实现将密码存储在 Principal
我认为这是不好的。
您可以通过创建get端点来获取主体:
@RestController
public class UserDetailsController {
@GetMapping("/userdetails")
public Principal getUserDetails(Principal user) {
return user;
}
}
这是我的实现,以获得更多的信息,例如 name
, id
, channelIds
等等。
@RestController
public class UserDetailsController {
// TODO: hide password.
@GetMapping("/userdetails")
public MyUserDetails getUserDetails(@CurrentSecurityContext(expression = "authentication.principal") Object user) {
return (MyUserDetails) user;
}
}
我的预期结果是密码为空。
我的实际结果是密码不是空的。e、 数据库中的密码是加密的 ewaejovra
,则主体中存储的密码 ewaejovra
.
这是我的实现
Web安全配置.java
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
...
}
myuserdetailsservice.java文件
@Service
public class MyUserDetailsService implements UserDetailsService {
private final UserMapper userMapper;
public MyUserDetailsService(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
Optional<UserModel> user = userMapper.getUser(s);
user.orElseThrow(() -> new UsernameNotFoundException("Username Not Found: " + s)); // TODO: who receives the Exception?
return user.map(MyUserDetails::new).get();
}
}
myuserdetails.java文件
public class MyUserDetails implements UserDetails {
private final String userId;
private final String username;
private String password;
private final boolean active;
private final Set<GrantedAuthority> authorities;
public MyUserDetails(UserModel user) {
this.userId = user.getId();
this.username = user.getUser();
this.password = user.getPassword();
this.active = user.getActive();
this.authorities = Set.of(new SimpleGrantedAuthority("ROLE_USER"));
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return active;
}
public String getUserId() {
return userId;
}
}
1条答案
按热度按时间jq6vz3qz1#
您不能从principle对象中删除密码,您可以避免在请求时发送它,但一旦发送,它将由principle接收,以便在spring security中使用它。
这实际上取决于您执行安全性的方式,例如,如果用户必须传递其凭据(
username
+password
)每次请求访问受保护的资源时,原则上您都会得到密码,这在最后是有意义的,密码只是安全所需的一些字符串。另一方面,如果您使用某个jwt访问令牌,消费者在执行成功登录后将收到该令牌,然后他将与您的服务器交换该令牌,以这种安全方式访问安全资源,您将看到
password
一年一次principle
对象,但在用户第一次登录之后,您将在principle对象中看到的唯一一段数据是访问令牌检查https://dzone.com/articles/spring-boot-security-json-web-tokenjwt-hello-world 更多信息