Grails spring-security-ui plugin and Bad credentials exception

The spring-security-ui plugin provides CRUD screens and user management workflows out of the box for spring security implementation. The most important is that it’s fully customizable. Together with spring-security-core plugin its gives you full implementation of security stack. Instalation is very simple but you have to consider one thing.

For example to install plugin with brand new app run:

grails create-app sample
grails install-plugin spring-security-core
grails s2-quickstart com.sample User Role

grails install-plugin mail
grails install-plugin jquery
grails install-plugin jquery-ui
grails install-plugin famfamfam

grails install-plugin spring-security-ui

grails run-app

And that’s it. You have CRUD flow for user management and login, register, forgot password functionalty.
Only problem is that you cannot login with registered users. Read along to see why.

Password encoding catch

Plugin have generated all classes for us but one thing you have to change manually.
Classes generated by spring-security-core plugins already have encodePassword executed before insert.
For example in User it looks like this:

	def beforeInsert() {
		encodePassword()
	}
	def beforeUpdate() {
		if (isDirty('password')) {
			encodePassword()
		}
	}
	protected void encodePassword() {
		password = springSecurityService.encodePassword(password)
	}

After you install spring-security-ui you may find that you cannot login using created users. You will receive error about bad credentials: org.springframework.security.BadCredentialsException: Bad credentials

The problem is that while registering new users controller generated by springsecurity.ui is encoding user password second time.
So you end up having password encoded twice. Password is encoded in controller and in User domain object.
You can remove encoding in domain object but this is not prefered because then you will have to remember to encode password when creating
User objects in BootStrap or anywhere else besides UserController.

Solution

Solution is to disable encoding in springsecurity.ui controllers by setting property in Config.groovy:

grails.plugins.springsecurity.ui.encodePassword = false

Other things to configure

There are also other things generated by plugin you may want to customize.
For example RegisterController and its views assume that your User domain class has an email field. If You don’t have smtp server then registration will fail. Be sure to rework the workflow (using the s2ui-override script) if you don’t want an email confirmation step.

grails s2ui-override register com.sample

Otherwise add an email field to User domain class and configure mail plugin.

You probably will need to change generated pages like register/index.gsp too get rid of email functionality. View register/index.gsp assumes that sendEmail model property is set to true after sucessfull registering user.