0
votes

I am trying to implement Spring Security for my Spring + Hibernate project.

But the hasRole('SUPER_ADMIN') that i write in the intercept-url tag is not working.

Please find the config that i have done below.

springSecurity.xml

<http auto-config="true" use-expressions="true">
        <intercept-url pattern="/admin**" access="hasRole('SUPER_ADMIN')" />
        <!-- access denied page -->
        <access-denied-handler error-page="/403" />
        <form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error" username-parameter="username"
            login-processing-url="/loginCheck" password-parameter="password" />
        <logout logout-success-url="/login?logout" />
        <!-- enable csrf protection -->
        <csrf />
    </http>

    <authentication-manager>
        <authentication-provider user-service-ref="myUserDetailsServices">
            <password-encoder hash="bcrypt" />
        </authentication-provider>
    </authentication-manager>

I am using the following auth provider

public class MyUserDetailsServices implements UserDetailsService {

    private UserDao userDao;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {

        User user = userDao.findByEmail(username);
        if (user == null) {
            throw new UsernameNotFoundException("User " + username + " not found");
        }
        List<GrantedAuthority> authorities = buildUserAuthority(user.getRoles());
        return buildUserForAuthentication(user, authorities);

    }

    private org.springframework.security.core.userdetails.User buildUserForAuthentication(User user, List<GrantedAuthority> authorities) {
        return new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), true, true, true, true, authorities);
    }

    private List<GrantedAuthority> buildUserAuthority(Set<Role> userRoles) {

        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

        for (Role userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getRoleName()));
        }

        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

        return Result;
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

}

The The above code is working fine. I am able to get the correct role and buildUserForAuthentication() method is returned with the SUPER_ADMIN role added in the authorities.

But still the hasRole('SUPER_ADMIN') is not working. I am not able to access the page http://127.0.0.1:8080/myproj/admin. The user is getting authenticated and logged in. But the above url is getting redirected to /403 (Access Denied).

Am i missing something? Please help.!

2

2 Answers

2
votes

The hasRole is working well. What is not working in your code is your wildcard on your springSecurity.xml. Change this

<intercept-url pattern="/admin**" access="hasRole('SUPER_ADMIN')" />

to

<intercept-url pattern="/admin/**" access="hasRole('SUPER_ADMIN')" />

Not sure why and how, but spring seems to add a leading slash why validating your url.

so having /admin/** will have the same effect as your intended /admin**.

0
votes

Got this rectified by adding 'ROLE_' to the rolename. Made it as ROLE_SUPER_ADMIN and it started working. I am assuming that every role should be prefixed with 'ROLE_' for spring security to work properly.

Thanks @storm_buster for the tip. :)