Spring Security 2.0.6 what calls the loadUserByNam

2019-08-19 12:23发布

问题:

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.

回答1:

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.