Custom Authentication Success Handler with Grails and Spring Security

It’s Sunday and instead of devoting this day to our Lord I will dedicate it to the great Machine and its coding brethren. The jokes aside, this is a quick show up of how to establish custom Authentication Success Handler if you are working with Grails Framework + Spring Security Core Plugin.

Well first, why would you need to alter the ‘normal’ behaviour  of the handler?

The answer: let’s say, you want to change the targetUrl for the specific authenticated user. Is that not enough? 🙂

HOW TO DO IT

With Spring and Java what you need to do is to implement the AuthenticationSuccessHandler interface. It has only one method to be implemented:

void onAuthenticationSuccess(HttpServletRequest var1, HttpServletResponse var2, Authentication var3);

With Grails and Spring Security Core plugin we follow the same path, just the ritual is a little bit different.

Spring Security Plugin use the AjaxAwareAuthenticationSuccessHandler  bean that extends SavedRequestAwareAuthenticationSuccessHandler and if you follow the hierarchy tree you will notice that at some point the needed interface is implemented at the upper classes. So what we need to do is just extend AjaxAwareAuthenticationSuccessHandler and define the bean in resources.groovy (оr .xml).

package com.wordpress.groggystuff.grails

import grails.plugin.springsecurity.web.authentication.AjaxAwareAuthenticationSuccessHandler
import org.springframework.security.core.Authentication

import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession

class GroggySuccessHandler extends AjaxAwareAuthenticationSuccessHandler {

    boolean userIsBadPerson = false

    @Override
    protected String determineTargetUrl(HttpServletRequest request,HttpServletResponse response) {

        if(userIsBadPerson){
            logger.info("This user is very nasty. Send him to /dev/null to rot.")
            return "/dev/null"
        }
        else {
            return super.determineTargetUrl(request, response)
        }
    }

    @Override
    public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response,
                                        final Authentication authentication) throws ServletException, IOException {
        try {
            checkIfTheUserIsBadPerson(request.getSession(),authentication)
            handle(request,response,authentication)
            super.clearAuthenticationAttributes(request)
        }
        finally {
            // always remove the saved request
            requestCache.removeRequest(request, response)
        }
    }

    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        String targetUrl = determineTargetUrl(request, response)

        if (response.isCommitted()) {
            logger.debug("Response has already been committed. Unable to redirect to " + targetUrl)
            return
        }

        redirectStrategy.sendRedirect(request, response, targetUrl)
    }


    private void checkIfTheUserIsBadPerson(HttpSession session, Authentication authentication){

        // do the groggy check to find if the user is a bad person
        // presume that the user is always a bad person
        userIsBadPerson = true
    }
}

When the user authenticates successfully onAuthenticationSuccess method is called. With this code the method determineTargetUrl will be always referenced when the user logins and from there we can easily change the targetUrl that the handle method redirects to. I wrote a logical check with which I check when to redirect and how to build my targetUrl in determineTargetUrl. Don’t forget to define the bean in resources.groovy .  The bean id must be the same as in the plugin, otherwise this class will be just ignored.

beans = {
    // other beans
    authenticationSuccessHandler(GroggySuccessHandler) {
        /* Reusing the security configuration */
        def conf = SpringSecurityUtils.securityConfig
        /* Configuring the bean */
        requestCache = ref('requestCache')
        redirectStrategy = ref('redirectStrategy')
        defaultTargetUrl = conf.successHandler.defaultTargetUrl
        alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault
        targetUrlParameter = conf.successHandler.targetUrlParameter
        ajaxSuccessUrl = conf.successHandler.ajaxSuccessUrl
        useReferer = conf.successHandler.useReferer
    }
}

And that’s it my lads and gals. (tested with Grails 2.5.0 and spring-security-core:2.0-RC4)

And a song as always.

Creating Java keystore from existing private key and certificate

With the bunch of programming codes and programs found on the Web this days, Code Signing Certificates are fact and necessity. But the people who are end-users or developers are still in process of adjusting the awareness what programs/scripts/code are safe and junk free and should be trusted before running them on local machine. With this little guide I want to help new people which are diving into this area of problems.

Different platforms offer different way for code signing their apps , and in this post I will focus just on Java based systems.

Java web and desktop apps are bound with keystore files that keep the certificate chains signed by Internet authorities. With this technique it is easy to make distinction from trusted to untrusted programs with investment of some time and money.

Generally the process of creating Java keystore that can sign applications(source codes) can be covered in couple of steps that include the client and the certificate issuer:

  1. The client creates keystore file and generates private and public key pair
  2. The client exports Code Signing Request from the keys with personal and trustworthy data
  3. The client sends the CSR to Certificate issuer and waits for approval. Normally it is contacted during pending time.
  4. Certificate Issuer sends to the client the signed certificate and probably additional intermediate/root chain certificates that need to be included into the keystore.
  5. The client imports the certificate (probably in pkcs7 format) into the original keystore that was used to generate the keys and CSR with the appropriate alias that was used during the creation of the keystore.
  6. The keystore is included in Java applications and referenced with the alias so to sign the JARs used in the apps.

However it can happen the client to receive private key that ought to be used, without previously creating a valid keystore and generating key pair within it. This received key was used for generating CSR and certificate request was already sent to authority.

Well at this point it gets confusing what is the next step that should be taken and is it possible this key to be used for creating a new keystore? Some will say it is not possible (and seems logical because keytool doesn’t allow it), you will need to create new keystore and generate key pair  and issue a new certificate request with the CSR exported from this keystore key pair. That’s not true though, there is always a way.

Let’s suppose the original request has been approved and you received valid certificate cert.crt. At this point you have private.key and trusted cert.crt.

This files need to be merged and exported into pkcs12 format with the help of libssl library.

openssl pkcs12 -export -in cert.crt -inkey private.key -certfile cert.crt -name <certificate(alias)_name> -out keystore.p12

Next this new generated keystore.p12 should be used to create new keystore in JKS format with the help of keytool from the JDK.

keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS
And that’s it voila! We have created keystore in jks format from existing private key.

After we have the keystore needed it is easy to import new certificates if required. Example:

keytool -import -trustcacerts -alias <alias(certificate)_name> -keystore keystore.jks -file <certificate_filename>

That’s it, three commands that will make your life easier.

SkeletorLead

Cheers,

Igor