How to set user role in Spring Security 3?

endertunc picture endertunc · Jul 23, 2014 · Viewed 14.4k times · Source

I am working on JAVA EE technologies to learn JSF-Spring-Hibernate vs... I am trying to do web application with diffirent user roles. Now, I have only one user role ROLE_USER. I could not change that role. I tried debug mod to understand how we set this role but I could not understand where it is happening.

So, my main problem is I can not create any other ROLE in my application. If I do not use <secured attributes="ROLE_USER" /> in my flow (I am using spring web-flow) everyone can reach that page. If I do only ROLE_USER. But I want to create new role named ROLE_ADMIN and only let ROLE_ADMIN to reach that page.

NOTE: I did not add all files here cause is spoken to me that only add related classes and files. If you need extra information please let me know.

This is the tutorial soruce code that I am following. https://code.google.com/p/jee-tutorial-youtube/source/browse/

security-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<security:http auto-config="true">
    <security:form-login login-page="/app/main"
        default-target-url="/app/account" />
    <security:logout logout-url="/app/logout"
        logout-success-url="/app/main" />
</security:http>

<security:authentication-manager>
    <security:authentication-provider
        user-service-ref="userServiceImp">
        <security:password-encoder hash="md5" />
    </security:authentication-provider>
</security:authentication-manager>

<bean id="daoAuthenticationProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="userServiceImp" />
    <property name="hideUserNotFoundExceptions" value="false" />
</bean>

<bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
    <constructor-arg>
        <ref bean="daoAuthenticationProvider" />
    </constructor-arg>
</bean>

This is my UserAuthenticationProviderServiceImp class where I authenticatethe the user.

 public boolean processUserAuthentication(Users user) {

        try {
                Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
                Authentication result = authenticationManager.authenticate(request);
                SecurityContextHolder.getContext().setAuthentication(result);

                return true;
        } catch(AuthenticationException e) {
                FacesContext.getCurrentInstance().addMessage(null, 
                                new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "Sorry!"));

                return false;
        }
}

And I figure out that this function, im my Service class, is called in processUserAuthentication.Then I thought this is the function where Roles are setted.

public UserDetails loadUserByUsername(String userName)
        throws UsernameNotFoundException {

    Users user = userDao.loadUserByUserName(userName);

    if (user == null) {
        throw new UsernameNotFoundException(String.format(
                getMessageBundle().getString("badCredentials"), userName));
    }

    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority("USER_ROLE"));
    User userDetails = new User(user.getUserName(), user.getPassword(),
            authorities);
    return userDetails;
}

Update:

In my project I have to use this syntax to create roles: ROLE_X where x is any string. Example; we can have ROLE_MYNAME but we can not have juts MYNAME or MYNAME_ROLE as role. It has to start with ROLE_. I am still trying to find what couses this problem. I will update If I found any answer.

EDIT: There is an detailed explanation why we has to use ROLE_ in this page; http://bluefoot.info/howtos/spring-security-adding-a-custom-role-prefix/

Answer

gad picture gad · Jul 23, 2014

Right now USER_ROLE is hardcoded in your application. Ideally User to Role mapping would come from Authorities table in database. This mapping info then can be retrieved using a DB query and then added to the authorities collection.

authorities.add(loadUserAuthorities(user.getUsername()));

protected List<GrantedAuthority> loadUserAuthorities(String username) {
    List<GrantedAuthority> authorities = null;
    Object[] params = { username };
    authorities = authoritiesByUsernameMapping.execute(params); // Query to get Authorities
    return authorities;      
}

Spring Security DB schema