Spring Security 2.0.6 调用 UserDetailSservice 的 loadUserByuserName 方法时

Posted

技术标签:

【中文标题】Spring Security 2.0.6 调用 UserDetailSservice 的 loadUserByuserName 方法时【英文标题】:Spring Security 2.0.6 what calls the loadUserByName method of an UserDetailService 【发布时间】:2011-07-17 07:49:02 【问题描述】:

我正在构建一个简单的 Sring MVC 应用程序。现在我正在尝试添加 Spring 安全性。我添加了一个customUserDetailsService,它使用DAO 来访问mysql 数据库并获取用户。

@Transactional(readOnly = true)
public class CustomUserDetailService implements UserDetailsService 

    @EJB(name = "UserDAOLocal")
    UserDAOLocal dao = null;

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException 
        System.out.println("Checking if this is invoked")
        UserDetails user = null;
        DBUsers dbUser = dao.findUserName(username);

        user = new User(dbUser.getUserName(), dbUser.getPassword(), true, true, true, true, getAuthorities(dbUser.getAccess()));
        return user;
    

    private GrantedAuthority[] getAuthorities(Integer access) 

        GrantedAuthority[] authList = new GrantedAuthority[2];

        authList[0] = new GrantedAuthorityImpl("ROLE_USER");
        if (access.compareTo(1) == 0) 
            authList[1] = new GrantedAuthorityImpl(("ROLE_ADMIN"));

        
        return authList;
    

我已将UserDetailsService 添加到Spring-security.xml

  <security:authentication-manager alias="authenticationManager">
    <security:authentication-provider user-service-ref="customUserDetailsService"/>
</security:authentication-manager>

<bean id="customUserDetailsService" class="service.CustomUserDetailService"/>

我将j_spring_security_check 作为login.jsp 页面上登录表单的操作。

当我输入有效的用户名和密码时,应用程序总是告诉我它是错误的。更重要的是,我找不到任何证据表明customUserDetailsService 随时运行。 (我使用System.out.println("Checking if this is invoked") 来检查服务器)。

是什么调用了CustomUserDetailsServiceloadUserByUsername() 方法?什么时候调用?

如何配置?

(我提供的所有代码可能都是不必要的:))

编辑: 这是 Spring-Security.xml 的其余部分

<security:http auto-config="true">


    <security:intercept-url pattern="/AddEmployee.htm" access="ROLE_ADMIN"/>
    <security:intercept-url pattern="/FireEmployee.htm" access="ROLE_ADMIN"/>
    <security:intercept-url pattern="/employees.htm" access="ROLE_USER"/>

    <security:form-login login-page="/login.htm"
authentication-failure-url="/login.htm?error=true"
login-processing-url="/j_spring_security_check.htm"
default-target-url="/common.htm"/>

    <security:logout
invalidate-session="true"
logout-success-url="/login.htm"
logout-url="/logout.htm"/>

</security:http>

我通过像这样编辑身份验证提供程序解决了这个问题。我决定不使用 DAO 和用户数据库。并在 xml 文件中使用硬编码的用户

 <security:authentication-provider>
    <security:user-service>
        <security:user name="sam" password="sam123" authorities="ROLE_ADMIN,ROLE_USER" />
        <security:user name="pam" password="pam123" authorities="ROLE_USER" />
    </security:user-service>
</security:authentication-provider>

这很好用。

但我想知道为什么我的 customUserDetailService 从未使用过,并了解如何正确使用它。

【问题讨论】:

您可以在您的 webapp 中启用调试日志以获取更多信息。 您正在构建一个新应用程序,但使用的是旧版本的 Spring Security?你到底为什么要那样做?当前版本为 3.0.5 static.springsource.org/spring-security/site/reference.html @Sean Patrik Floyd 我正在学习教程。本教程使用了该版本。我尝试使用新版本。但是碰到了一些未知的标签问题。所以决定改用旧版本。此外,我正在尝试学习 Spring Security 概念。不是细节。 【参考方案1】:

分享更多配置。来自 Spring-security.xml 会有所帮助(如果可能的话)

Spring 安全性的设计使您的身份验证提供程序调用 UserDetailsServiceloadUserByUsername() 方法,该方法返回 userDetails 对象。 流程如下:

Authentication Manager 的任务是对用户进行身份验证。所以它将用户名发送到Authentication provider

Authentication Provider 调用loadUserByUsername() 方法并传递返回userDetails Object 的String 类型的用户名。

现在这个userDetails 对象包含所有必要的身份验证信息,例如用户名、密码、isEnabled 等。

现在,如果您想自定义 userDetailsService 以使用您的 Dao,您可以自定义它。

这就是您的身份验证过程的工作方式。 您可以参考此link 以获得更广泛的理解。

【讨论】:

另外认证管理器的别名有什么用?起初,当我尝试在服务器中部署 EAR 时,出现了一个部署错误,告诉我向身份验证管理器添加一个别名。

以上是关于Spring Security 2.0.6 调用 UserDetailSservice 的 loadUserByuserName 方法时的主要内容,如果未能解决你的问题,请参考以下文章

未调用 Spring Security j_spring_security_check

如何使用spring security使用空密码进行基本身份验证?

Spring-Security:认证后调用方法

调用 j_spring_security_logout 不起作用

spring security 没有调用 loadUserByUsername() 方法

Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置