Welcome

Enabling Acegi (1)

We have decided to use Acegi Security Framework in order to implement security requirements in our web based project, but might possibly have diverse security requirements, in addition to form based authentication and role based authorization, such as remoting support, domain object security, run-as capability, SSO, after invocation security, certificate based authentication which is integrated with Active Directory Services and so on.

We will most probably have to customize and modify some of its features, but Acegi definitely form a good basis for security architecture of our system. First step in making a system secure is to decide which authentication mechanism to use and characteristics of authorization process. One of our requirements is to provide users to authenticate themselves via X509 based client certificates which will be through enabling of SSL communication. Those certificates will hold distinguished name information which will further be used to validate their owners against Active Directory information. In summary, users first provide their client certificates and second their windows domain passwords to get authenticated.

Acegi provides a mechanism to implement form based authentication and allows us to obtain user credentials from any source, in our case X509 client certificates and Active Directory Server. Acegi uses Filters extensively to get its authentication and authorization services work, and each filter has its own particular role in the framework. It employs AuthenticationProcessingFilter in order to implement HTTP form based authentication. AuthenticationProcessingFilter come into process, if request url is: /j_acegi_security_check. Then it obtains username and password from request and further asks AuthenticationManager to authenticate against that information. AuthenticationProcessingFilter, as provided by Acegi, is not doing exactly what we want, it wants to extract username information itself from request, however, we want to provide this from our client certificate’s distinguished name. As a result, we extended AuthenticationProcessingFilter and modified the part in which it obtains username. Below is the modified filter;

public class TbsAuthenticationProcessingFilter extends AuthenticationProcessingFilter {
    protected String obtainUsername(HttpServletRequest request) {
        String username = null;
        X509Certificate cert = getUserCertificate(request);
        if(cert != null) {
            username = cert.getSubjectDN().getName();
        }
        return username;
    }
    private X509Certificate getUserCertificate(HttpServletRequest request) {
        if(request.isSecure()) {
            X509Certificate[] certs = (X509Certificate[]) request.
                getAttribute("javax.servlet.request.X509Certificate");
            if(certs != null) {
                return certs[0];
            }
        }
        return null;
    }
}

AuthenticationManager, then tries to authenticate user, but how? It consults its providers, for example PasswordDaoAuthenticationProvider, whether they can validate given authentication information. Unfortunately, Acegi, in its current distribution, does not provide a convenient PasswordAuthenticationDao to connect Active Directory Server and check if given username, password information is correct, but thanks God, there exists an LdapPasswordAuthenticationDao in Acegi;’s CVS repository, and we currently use it to connect Active Directory Server and perform authentication.