Grails and SAPUI5 are friends

Hello reader,

instead of the planned walk through the city park and drinking some beer(s) mother nature swinging moods changed my plans and in place of the shiny sun gave me hard rain and sour mouth. In a situation like that, alone and bored I decided to bore you too and share this short text about two good friends called Grails and SAPUI5 (respect to the OpenUI5 project too). 🙂

I’ve been working hard with the Grails framework this couple of years and different situations led me to different scenarios. Lately I found myself in situation that asked bringing closer the powerful SAP services to the web/mobile clients. And what is better that using the outsourced JavaScript MVC framework made by SAP called SAPUI5 or if you prefer the open source project name OpenUI5 in conjunction with the versatile Grails Framework.

If you’re familiar with Grails then you certainly know that with the latest 3++ versions of Grails there is great support for already established and pretty much famous frameworks/libraries AngularJS and ReactJS in forms of Grails app profiles and plugins. But there is no “official” support for interbridging SAPUI5 and Grails and that is the main motive for writing this blog post and sharing it with you.

SAPUI5 is a single paged application where all the magic is done with JS so what we need is a single html file or in this case a single gsp file. We use that file to define the paths to the SAPUI5 runtime (or sdk) resources and to init the main SAPUI5 application via short JavaScript code. SAPUI5 is best when used with the OData services and that its where this software shines, however it has also great support when working with JSON and provides us with swift JSONModel that we can use to fill up the application data. And because we have JSON then we must have the Restful Grails controllers that will provide us with well defined JSON.

So the situation is pretty simple: Grails connects us with the backend via web services (or else?) or it provides us the data on its own via GORM or something else. Then Grails transforms the data into a JSON format that is a sweet cake for the SAPUI5 to consume and make it look great both on web browsers and on any mobile clients (Smart phones, tablets etc.).

Well this won’t be worth a penny without a working example, right? Because that’s the cause I’ve published a little demo of Grails and SAPUI5 playing together that you can check it on github. In short words we have a Spring Security Core plugin for the authentication and authorization, the JSON Views plugin for making the JSON even easier and also an example how to make it work via rest based http calls if your clients is native app . And of course the SAPUI5 application itself.

Here’s the link to the repo.

Thanks for reading,

cheers.

 

 

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.