Recently at work, I had to work on setting up a Spring application to do Active Directory authentication and use our internal permissions service. After much googling and playing around I finally figured out how to get it all working. I suspect this may not be the best way to do this, but it works.
Set this up in your config XML
1 2 3 4 5 6 7 8 9 10 | <!-- Connect to AD --> <bean id="activeDirectoryAuthenticationProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider"> <constructor -arg value="YOURDOMAIN"></constructor> <constructor -arg value="ldap://YOURSERVER"></constructor> <property name="userDetailsContextMapper" ref="customDetailsMapper"></property> <property name="convertSubErrorCodesToExceptions" value="true"></property> </bean> <!-- add in your permissions --> <bean id="customDetailsMapper" class="Full path to CustomDetailsMapper class"></bean> |
Now, the CustomDetailsMapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package mypackage; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.apache.log4j.Logger; import org.springframework.ldap.core.DirContextOperations; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper; public class CustomUserDetailsMapper extends LdapUserDetailsMapper { protected static Logger logger = Logger.getLogger("CustomUserDetailsMapper"); private static final Collection<string> DEFAULT_PERMS = Arrays.asList("login"); @Override public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection< ? extends GrantedAuthority> authorities) { /** * at this point, the user has permissions based on groups in LDAP/AD. If * we used AD for permissions, this would be sufficient, but we want permissions * from elsewhere so we need to modify the permissions/authorities */ logger.info(" old authorities: "+authorities); UserDetails user = super.mapUserFromContext( ctx, username, getPermissions(username)); logger.info(" adjusted user: "+user); return user; } /** * gets permissions * * @param username the username to get permissions for * @return a Set of permissions for the user */ private Set<grantedauthority> getPermissions(String username) { Set</grantedauthority><grantedauthority> permissions = new HashSet</grantedauthority><grantedauthority>(); /** * get your permissions here - however you need to * then convert them to SimpleGrantedAuthority */ for (String perm : permissionsFromOtherSource) { permissions.add(new SimpleGrantedAuthority(perm)); } return permissions; } } </grantedauthority></string> |
NOTE: the blog’s java code formatter is messing this code up a bit (specifically the GrantedAuthority parts), but you should be able to get the gist of it. Basically, after the user is filled out from AD, we get a handle to it and we change the permissions on it.