我有一个Custom User类,它扩展了User(Spring Security)的类和Custome UserDetailsService类。此服务使用Hibernate服务方法查询数据库以获取用户详细信息。如果数据库中没有找到该userId的记录,而不是抛出UsernamNotFoundException,我想创建一个虚拟的Custom用户对象,并使用只读属性传递身份验证。但我不能让它工作,因为我不知道如何检索用户在登录页面上输入的密码值。我需要将它传递给自定义用户构造函数以使其正确验证..
那么,总而言之,无论如何都要检索用户在loadUserByUserName()方法内的登录页面上输入的密码?提前致谢
答案 0 :(得分:2)
我正在以类似的方式做一件当前的项目。我刚刚开始在过去的两周内进入Spring Security,但是在那段时间我真的已经深入研究了它(附带的源代码,在调试器中完成了它)。
我有一个自定义用户类,它扩展了 org.springframework.security.core.userdetails.User 和一个实现 org.springframework.security.core.userdetails.UserDetailsService <的自定义类/ em> interface。
如您所知, UserDetailsService 接口中的loadUserByUsername方法的签名指定将返回实现 UserDetails 接口的类。
Spring Security将采用实现 UserDetails 的类,并根据用户名和密码检查登录表单/基本身份验证/摘要身份验证/(您选择的身份验证方案)提供的用户名和密码在 UserDetails 中。
我还没有找到一种方法,您可以通过身份验证方案获取最终用户提供的凭据。如果你愿意的话,我可以在明天回到工作岗位时尝试一下(我在家里从记忆中写下来。
答案 1 :(得分:0)
我正在运行Spring 3.0.6 RELEASE和Spring Security 3.0.6 RELEASE。
我在调试器中运行了代码。您将无法从自定义 UserDetailsService 获取Authentication对象。
但是,我相信您可以创建自己的AuthenticationProvider:http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-services.html
请从Spring Security的 org.springframework.security.authentication.ProviderManager 中引用此代码段,该代码片段遍历AuthenticationProvider:
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
logger.debug("Authentication attempt using " + provider.getClass().getName());
try {
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
break;
}
} catch (AccountStatusException e) {
// SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
eventPublisher.publishAuthenticationFailure(e, authentication);
throw e;
} catch (AuthenticationException e) {
lastException = e;
}
}
如您所见,它遍历每个AuthenticationProvider并传入凭据。希望有所帮助!
菲利普
答案 2 :(得分:0)
我们可以通过扩展AbstractUserDetailsAuthenticationProvider来做类似于你所要求的事情。有一个方法retrieveUser(String _userName,UsernamePasswordAuthenticationToken _authToken),您可以覆盖它并将其放入您自己的自定义逻辑中。返回对象是UserDetails。因此,此时您可以创建自己的自定义UserDetails并将其返回到框架(注意:您也可以在此方法中设置只读属性)。
此时,Spring Security将不会尝试使用密码进行身份验证。他们将其留给您也可以覆盖的additionalAuthenticationChecks(UserDetails _userDetails,UsernamePasswordAuthenticationToken _authToken)方法。由于这是您进行密码验证的地方,因此可以跳过验证并让方法返回。此时,您的匿名用户将被验证。
最后将其添加到security.xml
<authentication-manager alias="authenticationManager">
<authentication-provider ref="appUserSecurityService" />
</authentication-manager>
我希望这有帮助!