SPRING:将自定义用户详细信息添加到 Spring 安全用户



我目前正在开发Spring MVC应用程序,我需要在登录时向我的Spring Security登录用户添加一个自定义字段(我插入用户名,密码,自定义值)。当用户登录时,此值需要在任何地方可用(例如,通过 pricipal.getValue)。

我阅读了很多关于自定义用户类和自定义服务的信息,但无法真正找到解决我的问题的工作解决方案......

任何帮助都会很棒!

就像 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;
    }
}

您只需使用自定义UserdetailsService配置WebConfigurerAdapter

@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 ...//
    }

}

下面是自定义UserDetails实现的示例:自定义用户详细信息

创建实现UserDetails接口的类。

public class User implements UserDetails {
    // Your user properties
    // implement methods
}

然后,一旦通过身份验证,您就可以像这样在项目中的任何位置访问此对象。

User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

我通过以下方式进行了研究。

帐户详细信息服务.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);
    }
}

自定义用户详细信息.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;
    }
}

如果要将角色作为ADMIN/USER发送角色,请不要直接userRole.getRole(),而是将其编写为"ROLE_" + userRole.getRole()。这样您就可以无错误地运行代码。

例:

@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;
    }
}

相关内容

  • 没有找到相关文章

最新更新