如何在Custom UserDetailsS​​ervice中检索登录表单密码

时间:2011-10-12 17:59:53

标签: spring-mvc spring-security

我有一个Custom User类,它扩展了User(Spring Security)的类和Custome UserDetailsS​​ervice类。此服务使用Hibernate服务方法查询数据库以获取用户详细信息。如果数据库中没有找到该userId的记录,而不是抛出UsernamNotFoundException,我想创建一个虚拟的Custom用户对象,并使用只读属性传递身份验证。但我不能让它工作,因为我不知道如何检索用户在登录页面上输入的密码值。我需要将它传递给自定义用户构造函数以使其正确验证..

那么,总而言之,无论如何都要检索用户在loadUserByUserName()方法内的登录页面上输入的密码?提前致谢

3 个答案:

答案 0 :(得分:2)

我正在以类似的方式做一件当前的项目。我刚刚开始在过去的两周内进入Spring Security,但是在那段时间我真的已经深入研究了它(附带的源代码,在调试器中完成了它)。

我有一个自定义用户类,它扩展了 org.springframework.security.core.userdetails.User 和一个实现 org.springframework.security.core.userdetails.UserDetailsS​​ervice <的自定义类/ em> interface。

如您所知, UserDetailsS​​ervice 接口中的loadUserByUsername方法的签名指定将返回实现 UserDetails 接口的类。

Spring Security将采用实现 UserDetails 的类,并根据用户名和密码检查登录表单/基本身份验证/摘要身份验证/(您选择的身份验证方案)提供的用户名和密码在 UserDetails 中。

我还没有找到一种方法,您可以通过身份验证方案获取最终用户提供的凭据。如果你愿意的话,我可以在明天回到工作岗位时尝试一下(我在家里从记忆中写下来。

答案 1 :(得分:0)

我正在运行Spring 3.0.6 RELEASE和Spring Security 3.0.6 RELEASE。

我在调试器中运行了代码。您将无法从自定义 UserDetailsS​​ervice 获取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>

我希望这有帮助!