One more approach for diagnosing spring-security-core login errors

I wrote up a few techniques to help determine what is happening when you are unable to authenticate with use the Grails spring-security-core plugin here and since then I’ve had to use them myself a couple of times. I have everything configured to easily debug the issues and often that ends up being the best approach, but not everyone is comfortable with a debugger, or not excited about the prospect of configuring their IDE with JAR sources and the other steps needed to properly debug. This and this Stack Overflow question prompted me to document another approach.

This one is a rather dangerous and should be removed as soon as the issue is resolved because it prints cleartext passwords to the console, which is a huge security risk.

There are a handful of places where the cleartext password is available, but I think the most convenient is in the additionalAuthenticationChecks method of DaoAuthenticationProvider. The arguments to the method are the UserDetails instance, which will have the hashed password from the database, and the UsernamePasswordAuthenticationToken which will have the cleartext password.

To access this, create a subclass of DaoAuthenticationProvider:

package deletethisasap

import as UPAT

class MyDaoAuthenticationProvider extends DaoAuthenticationProvider {

  protected void additionalAuthenticationChecks(UserDetails ud, UPAT auth) throws AuthenticationException {
    String hashedPassword = passwordEncoder.encodePassword(
         auth.credentials, null)
    boolean ok = passwordEncoder.isPasswordValid(
         ud.password, auth.credentials, null)
    println "Cleartext: '$auth.credentials' from DB: '$ud.password' hashed '$hashedPassword' Valid: $ok"
    super.additionalAuthenticationChecks ud, auth

and register it with the same bean name in grails-app/conf/spring/resources.groovy:

import deletethisasap.MyDaoAuthenticationProvider

beans = {
  daoAuthenticationProvider(MyDaoAuthenticationProvider) {
    userDetailsService = ref('userDetailsService')
    passwordEncoder = ref('passwordEncoder')
    userCache = ref('userCache')
    saltSource = ref('saltSource')
    preAuthenticationChecks = ref('preAuthenticationChecks')
    postAuthenticationChecks = ref('postAuthenticationChecks')
    authoritiesMapper = ref('authoritiesMapper')
    hideUserNotFoundExceptions = true

It prints the hashed password and the cleartext password, and the cleartext password hashed for comparison. This won’t necessarily be the same as the value from the database, for example when using bcrypt, but the encoder has an isPasswordValid method to verify that they’re equivalent, so that is also printed.

This code assumes that you’re using standard form-based authentication (i.e. DaoAuthenticationProvider) and that you’re not using a salt. If you are using salted passwords, dependency-inject the saltSource bean and use it in the encodePassword and isPasswordValid methods.

2 Responses to “One more approach for diagnosing spring-security-core login errors”

  1. Joe says:

    When are you planning to update the Security Plugin to use the released Spring Security? I see that you checked in changes but the site with the plugin details still shows the October release?


  2. Dear Burt Beckwith,

    I was trying to find your e-mail on Harvard Extension School website but ended up here, on your blog page (and I glad I did it!). I am very interested in taking a class you are offering this Fall but am a bit concern about prerequisite requirements. I have some educational experience with Java (including classes, objects, and design patterns). In addition, I am familiar with PHP and mySQL. Will it be enough to follow the course?

Leave a Reply

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.