I was recently working on a project where there was a need to create custom web services that would connect to Alfresco and other back end systems. For a variety of reasons, it was decided to use Spring Boot as the framework for implementing these web services. One of the requirements was to use HTTP basic authentication when calling the web services and authenticate the user against Active Directory (AD) making sure that the user was also a member of specific group(s). This seems like a very simple requirement and my first thought was to use Spring Security with annotations to do this.
The key to implementing this was to create a new ActiveDirectoryLdapAuthenticationProvider when configuring the AuthenticationManagerBuilder and applying that with the correct settings. This is done by creating a class to extend WebSecurityConfigurerAdapter and overriding the configure(AuthenticationManagerBuilder auth) method. The setSearchFilter() method is used to change the LDAP query from the default to whatever is set in the application.properties.
The default user search filter is:
(&(objectClass=user)(userPrincipalName={0})
The user search filter can be changed as needed. It is an LDAP query that replaces the userPrincipalName substitution {0} with username@domain. In this case, a check was added to see if the user is also a member of a specific group using a “memberof” attribute. This may be different depending on how you have set up Active Directory. Use a tool like Apache Directory Studio to test your query.
(&(objectClass=user)(userPrincipalName={0})(memberof=CN=ServiceAccounts,OU=alfresco,DC=mycompany,DC=com))
A final change made in the overriding method was to set erase credentials to false ( “auth.eraseCredentials(false);” ) in order to make the password available for later use in the web service. The user name and password were needed to make web services calls to Alfresco. By default, the password is cleared.
The below code snippet shows how the user name and password were obtained. This is used within the service that makes calls to Alfresco.
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); String userName = auth.getName(); String password = (String)auth.getCredentials();
Complete class used to configure Spring Security for the project.
package com.mycompany; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider; @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Value("${ldap.url:ldap://mycompany.com:389}") private String url; @Value("${ldap.domain}:mycompany.com") private String domain; @Value("${ldap.userDNPattern:}") private String userDNPattern; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().fullyAuthenticated() .httpBasic(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { ActiveDirectoryLdapAuthenticationProvider adProvider = new ActiveDirectoryLdapAuthenticationProvider(domain,url); adProvider.setConvertSubErrorCodesToExceptions(true); adProvider.setUseAuthenticationRequestCredentials(true); // set pattern if it exists // The following example would authenticate a user if they were a member // of the ServiceAccounts group // (&(objectClass=user)(userPrincipalName={0}) // (memberof=CN=ServiceAccounts,OU=alfresco,DC=mycompany,DC=com)) if (userDNPattern != null && userDNPattern.trim().length() > 0) { adProvider.setSearchFilter(userDNPattern); } auth.authenticationProvider(adProvider); // don't erase credentials if you plan to get them later // (e.g using them for another web service call) auth.eraseCredentials(false); } }
Using Spring Security makes it very easy to add Active Directory support with HTTP basic authentication.
To learn more, or for help with your ECM system, contact us today.