skip to Main Content

This link works well for a single user/password HTTP basic auth
http://lambda.fortytools.com/post/26977061125/servlet-filter-for-http-basic-auth

Does anyone have any snippets for HTTP basic auth that authenticates against ActiveDirectory user/password?

2

Answers


  1. You could take a look at this example here and change the source e.g. from here to use the code from the first link.

    Link#1 content:

    public class ADAuthenticator 
    {
      private String domain;
      private String ldapHost;
      private String searchBase;
    
      public ADAuthenticator()
      {
        this.domain = "<your domain>";
        this.ldapHost = "ldap://<your AD controller>";
        this.searchBase = "your AD root e.g. dc=abbl,dc=org";
      }
    
      public ADAuthenticator(String domain, String host, String dn)
      {
        this.domain = domain;
        this.ldapHost = host;
        this.searchBase = dn;
      }
    
      public Map authenticate(String user, String pass)
      {
        String returnedAtts[] ={ "sn", "givenName", "mail" };
        String searchFilter = "(&(objectClass=user)(sAMAccountName=" + user + "))";
    
        //Create the search controls
        SearchControls searchCtls = new SearchControls();
        searchCtls.setReturningAttributes(returnedAtts);
    
        //Specify the search scope
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, ldapHost);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, user + "@" + domain);
        env.put(Context.SECURITY_CREDENTIALS, pass);
    
        LdapContext ctxGC = null;
    
        try
        {
          ctxGC = new InitialLdapContext(env, null);
          //Search objects in GC using filters
          NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
          while (answer.hasMoreElements())
          {
            SearchResult sr = (SearchResult) answer.next();
            Attributes attrs = sr.getAttributes();
            Map amap = null;
            if (attrs != null)
            {
              amap = new HashMap();
              NamingEnumeration ne = attrs.getAll();
              while (ne.hasMore())
              {
                Attribute attr = (Attribute) ne.next();
                amap.put(attr.getID(), attr.get());
              }
              ne.close();
            }
              return amap;
          }
        }
        catch (NamingException ex)
        {
          ex.printStackTrace();
        }
    
        return null;
      }
    }
    

    Link#2 content:

    public class BasicAuthenticationFilter implements Filter {
    
      /** Logger */
      private static final Logger LOG = LoggerFactory.getLogger(BasicAuthenticationFilter.class);
    
      private String username = "";
    
      private String password = "";
    
      private String realm = "Protected";
    
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
        username = filterConfig.getInitParameter("username");
        password = filterConfig.getInitParameter("password");
        String paramRealm = filterConfig.getInitParameter("realm");
        if (StringUtils.isNotBlank(paramRealm)) {
          realm = paramRealm;
        }
      }
    
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
          throws IOException, ServletException {
    
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
    
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null) {
          StringTokenizer st = new StringTokenizer(authHeader);
          if (st.hasMoreTokens()) {
            String basic = st.nextToken();
    
            if (basic.equalsIgnoreCase("Basic")) {
              try {
                String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8");
                LOG.debug("Credentials: " + credentials);
                int p = credentials.indexOf(":");
                if (p != -1) {
                  String _username = credentials.substring(0, p).trim();
                  String _password = credentials.substring(p + 1).trim();
    
                  if (!username.equals(_username) || !password.equals(_password)) {
                    unauthorized(response, "Bad credentials");
                  }
    
                  filterChain.doFilter(servletRequest, servletResponse);
                } else {
                  unauthorized(response, "Invalid authentication token");
                }
              } catch (UnsupportedEncodingException e) {
                throw new Error("Couldn't retrieve authentication", e);
              }
            }
          }
        } else {
          unauthorized(response);
        }
      }
    
      @Override
      public void destroy() {
      }
    
      private void unauthorized(HttpServletResponse response, String message) throws IOException {
        response.setHeader("WWW-Authenticate", "Basic realm="" + realm + """);
        response.sendError(401, message);
      }
    
      private void unauthorized(HttpServletResponse response) throws IOException {
        unauthorized(response, "Unauthorized");
      }
    
    }
    
    Login or Signup to reply.
  2. At this link you can find a good example using Spring Security.

    Basically you should create a class to extend WebSecurityConfigurerAdapter and overriding the configure(AuthenticationManagerBuilder auth) method.

    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);
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search