Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling roles when authenticated to active directory with spring security 3.1

I'm trying to use a authenticate with an Active directory using Spring Security 3.1. I get authenticated and all is well.

<sec:ldap-server id="ldapServer" url="ldap://ldap/dc=sub,dc=domain,dc=com" port="389" />

<sec:authentication-manager erase-credentials="true"  >
    <sec:authentication-provider ref="ldapActiveDirectoryAuthProvider" />
</sec:authentication-manager>

<bean id="ldapActiveDirectoryAuthProvider" 
        class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <constructor-arg value="domain" />
    <constructor-arg value="ldap://server:389/"/> 
</bean>

Now to the question. How do I handle roles for the user so that I can setup my filters?

eg.

<sec:intercept-url pattern="/**" access="ROLE_USER"/>

Solution

I found out how to do this by using the UserDetailContextMapper and map my AD groups to ROLE_USER,ROLE_ADMIN etc.

    <bean id="ldapActiveDirectoryAuthProvider" 
        class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <constructor-arg value="domain" />
    <constructor-arg value="ldap://host:389/"/> 
    <property name="userDetailsContextMapper" ref="tdrUserDetailsContextMapper"/>
    <property name="useAuthenticationRequestCredentials" value="true"/>
</bean>

<bean id="tdrUserDetailsContextMapper" class="com.bla.bla.UserDetailsContextMapperImpl"/>

Mapper class:

public class UserDetailsContextMapperImpl implements UserDetailsContextMapper, Serializable{
    private static final long serialVersionUID = 3962976258168853954L;

    @Override
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authority) {

        List<GrantedAuthority> mappedAuthorities = new ArrayList<GrantedAuthority>();


        for (GrantedAuthority granted : authority) {

            if (granted.getAuthority().equalsIgnoreCase("MY USER GROUP")) {
                mappedAuthorities.add(new GrantedAuthority(){
                    private static final long serialVersionUID = 4356967414267942910L;

                    @Override
                    public String getAuthority() {
                        return "ROLE_USER";
                    } 

                });
            } else if(granted.getAuthority().equalsIgnoreCase("MY ADMIN GROUP")) {
                mappedAuthorities.add(new GrantedAuthority() {
                    private static final long serialVersionUID = -5167156646226168080L;

                    @Override
                    public String getAuthority() {
                        return "ROLE_ADMIN";
                    }
                });
            }
        }
        return new User(username, "", true, true, true, true, mappedAuthorities);
    }

    @Override
    public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) {
    }
}
like image 486
heldt Avatar asked Jan 12 '12 13:01

heldt


People also ask

How does Spring Security authentication work internally?

The Spring Security Architecture There are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication. Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object.

How does Spring Security hasRole work?

By default, Spring Security uses a thread-local copy of this class. This means each request in our application has its security context that contains details of the user making the request. To use it, we simply call the static methods in SecurityContextHolder: Authentication auth = SecurityContextHolder.


1 Answers

You can also inject a GrantedAuthoritiesMapper which was introduced in 3.1 as a general strategy for modifying the authorites. Plus you might want to use SimpleGrantedAuthority for the GrantedAuthority implementation. Alternatively, you could use an enum since you have a fixed set of values:

enum MyAuthority implements GrantedAuthority {
    ROLE_ADMIN,
    ROLE_USER;

    public String getAuthority() {
        return name();
    }
}


class MyAuthoritiesMapper implements GrantedAuthoritiesMapper {

    public Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> authorities) {
        Set<MyAuthority> roles = EnumSet.noneOf(MyAuthority.class);

        for (GrantedAuthority a: authorities) {
            if ("MY ADMIN GROUP".equals(a.getAuthority())) {
                roles.add(MyAuthority.ROLE_ADMIN);
            } else if ("MY USER GROUP".equals(a.getAuthority())) {
                roles.add(MyAuthority.ROLE_USER);
            }
        }

        return roles;
    }
}
like image 175
Shaun the Sheep Avatar answered Sep 21 '22 14:09

Shaun the Sheep