Spring Security 2.0.6 调用 UserDetailService 的 loadUserByName 方法

发布于 2024-10-22 18:08:57 字数 3068 浏览 2 评论 0原文

我正在构建一个简单的 Sring MVC 应用程序。现在我正在尝试添加 Spring 安全性。我添加了一个 customUserDetailsS​​ervice,它使用 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;
    }
}

我已将 UserDetailsS​​ervice 添加到 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 页面上登录表单的操作。

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

什么会调用 CustomUserDetailsS​​erviceloadUserByUsername() 方法?什么时候调用它?

我该如何配置它?

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

编辑: 这是 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从未被使用过,并学习如何正确使用它。

I'm building a simple Sring MVC app. And now i'm trying to add Spring security. I've added a customUserDetailsService that uses a DAO to access a MySql database and get users.

@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;
    }
}

And i've added the UserDetailsService to the Spring-security.xml.

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

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

I put j_spring_security_check as the action to the login form on the login.jsp page.

When i enter a valid username and a password the app always tells it's wrong. What's more is i can't find any evidence that the customUserDetailsService is running at anytime. (I used System.out.println("Checking if this is invoked") to check on the server).

What invokes the loadUserByUsername() method of the CustomUserDetailsService? When is it invoked?

How can i configure it?

(All the codes i supplied might be unnecessary :))

EDIT:
Here is the rest of the 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>

I worked around the problem by editing the authentication provider like this. I decided not use DAO, and user database. and used hard coded users inside the xml file

 <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>

This works perfectly.

But i would like to know why my customUserDetailService was never used, And learn how to use it correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

标点 2024-10-29 18:08:57

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

Spring security 的设计使您的身份验证提供程序调用返回 userDetails 对象的 UserDetailsS​​erviceloadUserByUsername() 方法。
流程如下:

  • 身份验证管理器的任务是对用户进行身份验证。因此它将用户名发送到身份验证提供程序

  • Authentication Provider 调用 loadUserByUsername() 方法并传递 String 类型的用户名,该用户名返回 userDetails 对象。

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

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

这就是您的身份验证过程的工作原理。
您可以参考此<强>链接以获得更广泛的理解。

Sharing more config. from Spring-security.xml would help(if possible)

Spring security is Designed so that your Authentication provider calls loadUserByUsername() method of the UserDetailsService which returns userDetails Object.
Process is as follows:

  • Task of Authentication Manager is to Authenticate the user. So it sends the user name to Authentication provider.

  • Authentication Provider calls loadUserByUsername() method and passes user name of type String which returns userDetails Object.

  • Now this userDetails object contains all necessary information for authentication, such as username, password, isEnabled etc.

Now if you want to customize userDetailsService for using your Dao you can customize it.

This is how your authentication process works.
You can refer this link for broader understanding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文