为啥我的 loadUserByUsername 不起作用?
Posted
技术标签:
【中文标题】为啥我的 loadUserByUsername 不起作用?【英文标题】:Why is my loadUserByUsername not working?为什么我的 loadUserByUsername 不起作用? 【发布时间】:2012-06-11 15:28:57 【问题描述】:我正在使用 Spring Security 3。我有自己的身份验证提供程序。
这是我目前所拥有的:
security-app-context.xml
<authentication-manager>
<authentication-provider user-service-ref="detailsService" />
</authentication-manager>
<beans:bean id="loginSuccessHandler" class="com.myapp.security.LoginSuccessHandler" />
<beans:bean id="loginFailureHandler" class="com.myapp.security.LoginFailureHandler" />
<beans:bean id="detailsService" class="com.myapp.security.UserDetailService" />
用户详细信息服务
public class UserDetailService implements UserDetailsService
private DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
String hql = "from Users where username = :username";
List<Users> list = null;
try
IO io = new IO("common_web");
IOQuery query = new IOQuery();
query.setStatement(hql);
query.setParameter(new IOParameter("username", username));
list = io.runQuery(query);
if (list.isEmpty())
return null;
catch (Exception ex)
ex.printStackTrace();
// THIS WORKS. I HAVE A VALID USER FROM DB
return (UserDetails) list.get(0);
此代码只是一个简单的示例。在“// THIS WORKS...”这一点上,我确实有来自我们数据库的Users
记录。但是当我返回这个对象时,我仍然没有通过身份验证。
请注意,Users
是一个 Hibernate 表对象。
我错过了什么?
【问题讨论】:
【参考方案1】:仅仅因为返回了 UserDetails 并不意味着您将通过身份验证。 DaoAuthenticationProvider 会进行许多检查以确保返回的用户应该经过身份验证。例如,它确保用户名和密码匹配、帐户未过期、帐户未锁定等。一个常见的问题是返回一个不包含任何 GrantedAuthority 的 UserDetails,这会导致 UsernamePasswordAuthenticationToken 指示用户不是已通过身份验证。
您是否尝试过为 org.springframework.security 启用调试日志记录?这可以解释什么是错的。如果您不熟悉日志记录,Spring(和 Spring Security)使用 commons-logging,您可以在 Spring 参考中找到 logging guide。
PS 正如 UserDetailsService 接口中所述,loadUserByUsername 永远不应返回 null。而是抛出一个 UsernameNotFoundException
【讨论】:
【参考方案2】:由于Users
类正在实现UserDetails
接口,请确保您从getAuthorities 方法返回GrantedAuthority
列表而不是null。此外,其他验证方法应返回适当的值以指示用户有效。例如:
@Override
public List<GrantedAuthority> getAuthorities()
return AuthorityUtils.createAuthorityList("VALID_USER_ROLE");
@Override
public boolean isAccountNonExpired()
return true;
@Override
public boolean isAccountNonLocked()
return true;
@Override
public boolean isCredentialsNonExpired()
return true;
@Override
public boolean isEnabled()
return true;
【讨论】:
以上是关于为啥我的 loadUserByUsername 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
什么时候调用loadUserByUsername? (春季安全)
Spring Security 2.0.6 调用 UserDetailSservice 的 loadUserByuserName 方法时
JAVA——springSecurity——自定义配置的一些补充:Anonymous匿名用户重写loadUserByUsername()方法自定义WebSecurityConfig配置等
JAVA——springSecurity自定义配置的一些补充:Anonymous匿名用户重写loadUserByUsername()方法自定义WebSecurityConfig配置等
我在哪里从 Spring Security 中获取“用户名”值以传递给 UserDetailsService 接口的 loadUserByUsername(String username) 方法