How to set user role in Spring Security 3?
Asked Answered
D

1

6

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/

Dizon answered 23/7, 2014 at 14:13 Comment(0)
W
0

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

Wareroom answered 23/7, 2014 at 17:14 Comment(7)
authorities.add(new SimpleGrantedAuthority("USER_ROLE")); I think this is the line that we set user authorities as a hardcode, right? So, If I write authorities.add(new SimpleGrantedAuthority("ROLE_X")); then change the secured tag like <secured attributes="ROLE_X" /> I should work, right? But It just does not. I read some artical about getting roles from database but firstlty I want to be sure it is work or not. Please let me know If I misunderstood.Dizon
Whatever you just posted should work, hard coding the authority to ROLE_ADMIN. Can you enable debug for org.springframework.security and check what the logs say for the url you are trying to access.Wareroom
I add log4j.category.org.springframework.security=DEBUG to my log4j file then I got this log.(pastebin.com/e5HX7T4Y) I copied from the console but it shows me part of it. And stackoverflow did not let me put here so I pasted to pastebin. Where I can reach the full log file.This is my log4j file: pastebin.com/x8W2ye45Dizon
@user1921974 Are you using userid wer? From the logs it looks like the user is getting role - TEST_ROLE. SecurityContext stored to HttpSession: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@9e7d34a3: Principal: org.springframework.security.core.userdetails.User@1cb64: Username: wer; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: TEST_ROLE; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: TEST_ROLE'Wareroom
I could not understand what do you mean by saying userid wer? But, I found the problem. We need to use this syntax to be able to create roles. The syntax is ROLE_X where X is any string. I wrote that but I did it wrong (poor me, sorry). We can have ROLE_TEST but we can not use TEST_ROLE or TEST as role. I do not know why we have to use ROLE_ but it work that way. My search is still going to found real reason of that ;)Dizon
@user1921974 In the logs you provided I see username Username: wer; Password: [PROTECTED] Authorities: TEST_ROLE. Is this the user you are trying to test? If so the user's role is being set as ROLE_TEST. You need to figure from this role is getting set.Wareroom
So sorry, I forgot that I was just trying random usernames and wer is one of them :). As I mentioned before problem was syntax. By the way, thanks for help ;)Dizon

© 2022 - 2024 — McMap. All rights reserved.