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() {
	def beforeUpdate() {
		if (isDirty('password')) {
	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: 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 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.

Spring MVC speaking Json or XML

In Spring MVC we can find a nice way of resolving view by type of request. This class is called ContentNegotiatingViewResolver.

It uses the requested media type to find correct View for a request. Task to pick most appropriate view is done by ViewResolvers that are either set expilicty or are taken from application context.

Here is an example of ContentNegotiatingViewResolver with JSON an Xml views provided:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1"/>
    <property name="mediaTypes">
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>

    <property name="defaultViews">
          <!-- JSON-->
          <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

          <!-- XML-->
          <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                  <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                      <property name="autodetectAnnotations" value="true"/>

MappingJacksonJsonView is a View that renders JSON content by serializing the model for the current request using Jackson’s ObjectMapper.

For Xml view we can use Jaxb or XStream. Not much difference beetween them:

Now different types of call to application will cause different return types:
http://localhost/ingredient/list.xml , XML file.
http://localhost/ingredient/list.json , JSON file.
http://localhost/ingredient/list, default view resolver.

There are also other View resolvers like for RSS, velocity or freemarker available.You can find them in: org/springframework/web/servlet/view package.

Travis, Code Climate, BuildCoint – ideas for better quality


Travis is a younger brother of Jenkins. Its a distributed build system for the open source community.
From may 2012 ( after fixing issue 242) its also avalible for your organization repositories (if you have admin rights).
You can connect it to you github project using service hooks.


Code Climate is service providing software metrics for Ruby apps. Since Jul 10th, 2012 it became free for Open Source project. It offers realtime metrics, activity feeds and email reports.

Since its free I added one of my first ruby project repository to see some metrics:

So metrics on current state of project for all classes was A. Code climate discovered one code smell: “Complex method” for one of methods. Beside this its showing LOC, code duplicates and some other metrics.

Code climate supports badges like travis. On project page there are snippets make it easy to add a link to Code Climate from your README.


And last is most interesting project named: BuildCoin.
As their page says its: “The Ultimate CI Game”. Project is in beta mode still and i am waiting for invitation code. The idea is quite simple: platform offers real-time dashboard and based on it you can setup some bonus games.
I imagine it would be something like: 100 coins for team if all major bugs will be fixed till the end of month.
Or 50 coins for improving code coverage to 80%. I think that after some practise with bonus systems its possible to develop some nice motivational bonus system for developers and have a lot of fun from daily jobs.