3
votes

I am new to Grails. I've configured the spring security plugin core 2.0 RC2. I am able to log in with a user stored in my database. I have configured a custom login form and when I attempt to access secure URLs without being logged in, I am redirected to my custom form. However, I have not been able to display error messages when I use a bad password or non-existent login.

I have the following snippet in my Grails.config:

grails.plugin.springsecurity.auth.loginFormUrl = '/user/login'
grails.plugin.springsecurity.failureHandler.defaultFailureUrl  = '/user/login'

This seems to work. I do get to my form successfully. I am using the default LoginController that comes with the plugin.

I have tried all the following on my form:

<g:eachError>
    <li><g:message error="${it}"/></li>
</g:eachError>
<g:eachError>
    <li>${it}</li>
</g:eachError>
<g:if test="${flash.message}">
    <li> class="error">${flash.message}</li>
</g:if>

None shows any errors. I can see that the login controller places errors in flash:

def authfail() {

    String msg = ''
    def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
    if (exception) {
        if (exception instanceof AccountExpiredException) {
            msg = g.message(code: "springSecurity.errors.login.expired")
        }
        else if (exception instanceof CredentialsExpiredException) {
            msg = g.message(code: "springSecurity.errors.login.passwordExpired")
        }
        else if (exception instanceof DisabledException) {
            msg = g.message(code: "springSecurity.errors.login.disabled")
        }
        else if (exception instanceof LockedException) {
            msg = g.message(code: "springSecurity.errors.login.locked")
        }
        else {
            msg = g.message(code: "springSecurity.errors.login.fail")
        }
    }

    if (springSecurityService.isAjax(request)) {
        render([error: msg] as JSON)
    }
    else {
        flash.message = msg
        redirect action: 'auth', params: params
    }
}

, but they seem to be gone when my page is displayed. I can see the error events are raised as I have created a security event listener which logs them. Grails and Spring Security experts, what am I missing?

1

1 Answers

1
votes

I would recommend the use of flash.error, which will put your error message in the flash scope. Something like this:

if (exception instanceof AccountExpiredException) {
        flash.error = g.message(code: "springSecurity.errors.login.expired")
}

Then in your gsp you will need the following:

<g:if test="${flash.error}">
<div class="errors">
    <ul><li>${flash.error}</li></ul>
</div>