Java SPRING:将自定义用户详细信息添加到 spring 安全用户
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41770156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SPRING: Add custom user details to spring security user
提问by counter1602
I'm currently working on a Spring MVC application and I need to add a custom field to my Spring Security log-in user right when I log in (I insert username, password, custom value). This value needs to be available on everywhere when the user is logged in (e.g. via pricipal.getValue).
我目前正在开发一个 Spring MVC 应用程序,我需要在登录时为我的 Spring Security 登录用户添加一个自定义字段(我插入用户名、密码、自定义值)。当用户登录(例如通过 pricipal.getValue)时,该值需要在任何地方都可用。
I read a lot about custom user classes and custom services, but can't really find a working solution for my problem...
我阅读了很多关于自定义用户类和自定义服务的内容,但无法真正为我的问题找到可行的解决方案......
Any help would be great!
任何帮助都会很棒!
采纳答案by Daniel Arechiga
Just like Avinash said, you can make your User
class implement UserDetails
and you can also implement UserDetailsService
and override corresponding methods to return the custom User
object:
就像 Avinash 说的,你可以让你的User
类实现UserDetails
,你也可以实现UserDetailsService
和覆盖相应的方法来返回自定义User
对象:
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
//get user from the database, via Hibernate
@Autowired
private UserDao userDao;
@Transactional(readOnly=true)
@Override
public UserDetails loadUserByUsername(final String username)
throws UsernameNotFoundException {
//CUSTOM USER HERE vvv
User user = userDao.findByUserName(username);
List<GrantedAuthority> authorities =
buildUserAuthority(user.getUserRole());
//if you're implementing UserDetails you wouldn't need to call this method and instead return the User as it is
//return buildUserForAuthentication(user, authorities);
return user;
}
// Converts user to spring.springframework.security.core.userdetails.User
private User buildUserForAuthentication(user,
List<GrantedAuthority> authorities) {
return new User(user.getUsername(), user.getPassword(),
user.isEnabled(), true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// add user's authorities
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
And you just configure your WebConfigurerAdapter
using the custom UserdetailsService
:
您只需WebConfigurerAdapter
使用 custom 进行配置UserdetailsService
:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//authorization logic here ...
}
@Bean
public PasswordEncoder passwordEncoder(){
// return preferred PasswordEncoder ...//
}
}
Here, a sample of a custom UserDetails
implementation:
custom UserDetails
这里是一个自定义UserDetails
实现的示例:
custom UserDetails
回答by Avinash
Create your class implementing UserDetails
interface.
创建您的类实现UserDetails
接口。
public class User implements UserDetails {
// Your user properties
// implement methods
}
And then, once authenticated, you can access this object anywhere in the project like this.
然后,一旦通过身份验证,您就可以像这样在项目中的任何地方访问此对象。
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
回答by viveknaskar
I had worked on this in the following way.
我通过以下方式处理过这个问题。
AccountDetailsService.java
帐户详细信息服务.java
@Service
public class AccountDetailsService implements UserDetailsService {
@Autowired
AccountRepository accountRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException, JSONException {
return loadUser(s);
}
public UserDetails loadUserByUsernameWithoutCredentials(String s) throws UsernameNotFoundException, JSONException {
CustomUserDetails customUserDetails=loadUser(s);
if (customUserDetails != null){
customUserDetails.eraseCredentials();
}
return customUserDetails;
}
private CustomUserDetails loadUser(String s) throws UsernameNotFoundException, JSONException {
Account userAccount = accountDbRepository.getAccountByUserName(s);
if (userAccount==null){
return null;
}
Collection<GrantedAuthority> grantedAuthoritySet = new HashSet<>();
for (int i=0; i<userAccount.getRoles().size();i++)
{
JSONObject jsonObject = new JSONObject(userAccount.getRoles().get(i));
String role = jsonObject.getString("role");
gas.add(new SimpleGrantedAuthority(role));
}
return new CustomUserDetails(userAccount.getEmail(),userAccount.getDisplayName(),userAccount.getUserName(),userAccount.getPassword(),userAccount.getEnabled(),gas);
}
}
CustomUserDetails.java
自定义用户详细信息.java
public class CustomUserDetails implements UserDetails {
private Collection<? extends GrantedAuthority> authorities;
private String email;
private String displayName;
private String password;
private String username;
private Boolean enabled;
private Boolean accountNonExpired;
private Boolean accountNonLocked;
private boolean credentialsNonExpired;
public CustomUserDetails(String email, String displayName, String username, String password, Boolean enabled, Collection<? extends GrantedAuthority> authorities) {
this.email = email;
this.displayName = displayName;
this.enabled=enabled;
this.username=username;
this.password=password;
this.accountNonExpired=true;
this.accountNonLocked=true;
this.credentialsNonExpired=true;
this.authorities=authorities;
}
public CustomUserDetails(String email, String displayName, String password, String username, Boolean enabled, Boolean accountNonExpired, Boolean accountNonLocked, boolean credentialsNonExpired, Collection<? extends GrantedAuthority> authorities) {
this.authorities = authorities;
this.email = email;
this.displayName = displayName;
this.password = password;
this.username = username;
this.enabled = enabled;
this.accountNonExpired = accountNonExpired;
this.accountNonLocked = accountNonLocked;
this.credentialsNonExpired = credentialsNonExpired;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
@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 accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
@Override
public boolean isEnabled() {
return enabled;
}
public void eraseCredentials(){
this.password=null;
}
}
回答by Sriraj
Don't directly wite userRole.getRole()
directly if you want to send the role as ADMIN/USER
instead write it as "ROLE_" + userRole.getRole()
. So that you can get the error-free run of your code.
userRole.getRole()
如果要发送角色,请不要直接直接 wite ,ADMIN/USER
而是将其写为"ROLE_" + userRole.getRole()
. 这样您就可以获得无错误的代码运行。
Example:
例子:
@Service("listUserDetailsService")
public class ListUserDetailsService implements UserDetailsService {
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException{
User user = userRepo.findByEmail(email);
if (user == null) {
throw new UsernameNotFoundException("Invalid User");
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+role.getName()));
}
return new org
.springframework
.security
.core
.userdetails
.User(user.getEmail(), user.getPassword(), grantedAuthorities);
}
}
private final UserRepo userRepo;
public ListUserDetailsService(UserRepo userRepo) {
this.userRepo = userRepo;
}
}