Spring Security 自定义 UserDetailsService 和自定义 User 类
Posted
技术标签:
【中文标题】Spring Security 自定义 UserDetailsService 和自定义 User 类【英文标题】:Spring Security custom UserDetailsService and custom User class 【发布时间】:2014-10-12 13:06:06 【问题描述】:我正在尝试在用户主体对象中保存其他数据。
我所做的是:
为我的现有用户类实现“UserDetails”接口,其中保存了我的其他数据(如电子邮件地址等)。
@Entity
public class User implements UserDetails
然后我创建了一个 UserDetailsService 实现:
@Service
public class UserDetailsServiceImpl implements UserDetailsService
@Autowired
UserDAO userDAO;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException
User user = userDAO.findOneByUsername(username);
if (user == null)
throw new UsernameNotFoundException("username " + username
+ " not found");
System.out.println("---------------------> FOUND ------------->"
+ user.getEmail());
return user;
最后一步是在我的安全配置中添加 UserDetailsService。
@Configuration
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception
auth.userDetailsService(userDetailsService());
// ...
@Override
protected void configure(HttpSecurity http) throws Exception
http.userDetailsService(userDetailsService());
// ...
@Override
protected UserDetailsService userDetailsService()
return userDetailsService;
我在控制台中看到“loadUserByName”被调用了两次(因为“找到”输出)。
当我尝试访问控制器中的主体对象时 ->
System.out.println(SecurityContextHolder.getContext()
.getAuthentication().getPrincipal());
我没有得到我的额外数据。 当我尝试将其转换为我的用户对象时,我得到一个无法转换的异常。
我有什么遗漏吗??
提前谢谢你。
【问题讨论】:
【参考方案1】:好的。我的问题隐藏在我没有发布的代码中。
我以为这个 detailsService 只是为了获取更多详细信息,但它用于登录本身。
我另外配置了“jdbcAuthentication”,spring 似乎总是使用它。
现在我只配置了 detailsService,一切正常。
编辑:
所以我只需要删除这段代码:
auth.jdbcAuthentication() .dataSource(dataSource)
* .passwordEncoder(passwordEncoder) .usersByUsernameQuery(
// ....
现在它也适用于我上面问题中的代码。
【讨论】:
【参考方案2】:创建扩展类:
public class CustomUserDetails extends org.springframework.security.core.userdetails.User
private User user;
public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities)
super(user.getName(), user.getPassword(), authorities);
this.user = user;
public CustomUserDetails(User user, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities)
super(user.getName(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.user = user;
public User getUser()
return user;
比把它添加到 UserDetailsService:
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException
UserDetails userDetails = null;
User user = userService.getByLogin(login);
userDetails = new CustomUserDetails(user,
true, true, true, true,
getAuthorities(user.getRole()));
return userDetails;
得到它!
(CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()
【讨论】:
这并没有改变任何东西。顺便提一句。你最后的代码 sn-p 给了我:“java.lang.ClassCastException: org.springframework.security.core.userdetails.User 不能被强制转换为 ..........CustomUserDetails” 你能调试你的应用程序并说出什么类会返回SecurityContextHolder.getContext().getAuthentication().getPrincipal()
吗?
类 org.springframework.security.core.userdetails.User以上是关于Spring Security 自定义 UserDetailsService 和自定义 User 类的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 之自定义UserDetails
Spring Boot + Spring Security自定义用户认证