title: grails spring security login is not working
body: <p>I am using grails 2.1.0. I have installed spring-security-core plugin. </p>
  
  <p>When I create user it is creating it. But when I try to login then it shows:</p>
  
  <p><code>"Sorry, we were not able to find a user with that username and password."</code> </p>
  
  <p>And there is also another fact that is when I use the same password for different user it does not save password with similar encoded value like for user 1 I have used password <code>123</code> which is saved in database like this </p>
  
  <p><code>d535ce213a0e8e4f9e724af47c46eea409ef401c03617b749da618a82890d743</code> </p>
  
  <p>and for user 2 I also used password <code>123</code> and this time it is saved like this </p>
  
  <p><code>0849ea79a2c1bca057ded06c3053fb5bc5d7ba52b50982e73e44894d4f3e0aa6</code></p>
  
  <p>I don't understand. Can anyone please help me on this ?</p>
  
  <p>my config.groovy >>></p>
  
  <pre><code>    // locations to search for config files that get merged into the main config;
  // config files can be ConfigSlurper scripts, Java properties files, or classes
  // in the classpath in ConfigSlurper format
  
  // grails.config.locations = [ "classpath:${appName}-config.properties",
  //                             "classpath:${appName}-config.groovy",
  //                             "file:${userHome}/.grails/${appName}-config.properties",
  //                             "file:${userHome}/.grails/${appName}-config.groovy"]
  
  // if (System.properties["${appName}.config.location"]) {
  //    grails.config.locations &lt;&lt; "file:" + System.properties["${appName}.config.location"]
  // }
  
  grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination
  grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format
  grails.mime.use.accept.header = false
  grails.mime.types = [
      all:           '*/*',
      atom:          'application/atom+xml',
      css:           'text/css',
      csv:           'text/csv',
      form:          'application/x-www-form-urlencoded',
      html:          ['text/html','application/xhtml+xml'],
      js:            'text/javascript',
      json:          ['application/json', 'text/json'],
      multipartForm: 'multipart/form-data',
      rss:           'application/rss+xml',
      text:          'text/plain',
      xml:           ['text/xml', 'application/xml']
  ]
  
  // URL Mapping Cache Max Size, defaults to 5000
  //grails.urlmapping.cache.maxsize = 1000
  
  // What URL patterns should be processed by the resources plugin
  grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*']
  
  // The default codec used to encode data with ${}
  grails.views.default.codec = "none" // none, html, base64
  grails.views.gsp.encoding = "UTF-8"
  grails.converters.encoding = "UTF-8"
  // enable Sitemesh preprocessing of GSP pages
  grails.views.gsp.sitemesh.preprocess = true
  // scaffolding templates configuration
  grails.scaffolding.templates.domainSuffix = 'Instance'
  
  // Set to false to use the new Grails 1.2 JSONBuilder in the render method
  grails.json.legacy.builder = false
  // enabled native2ascii conversion of i18n properties files
  grails.enable.native2ascii = true
  // packages to include in Spring bean scanning
  grails.spring.bean.packages = []
  // whether to disable processing of multi part requests
  grails.web.disable.multipart=false
  
  // request parameters to mask when logging exceptions
  grails.exceptionresolver.params.exclude = ['password']
  
  // configure auto-caching of queries by default (if false you can cache individual queries with 'cache: true')
  grails.hibernate.cache.queries = false
  
  environments {
      development {
          grails.logging.jul.usebridge = true
      }
      production {
          grails.logging.jul.usebridge = false
          // TODO: grails.serverURL = "http://www.changeme.com"
      }
  }
  
  // log4j configuration
  log4j = {
      // Example of changing the log pattern for the default console appender:
      //
      //appenders {
      //    console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
      //}
  
      error  'org.codehaus.groovy.grails.web.servlet',        // controllers
             'org.codehaus.groovy.grails.web.pages',          // GSP
             'org.codehaus.groovy.grails.web.sitemesh',       // layouts
             'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
             'org.codehaus.groovy.grails.web.mapping',        // URL mapping
             'org.codehaus.groovy.grails.commons',            // core / classloading
             'org.codehaus.groovy.grails.plugins',            // plugins
             'org.codehaus.groovy.grails.orm.hibernate',      // hibernate integration
             'org.springframework',
             'org.hibernate',
             'net.sf.ehcache.hibernate'
  }
  
  // Added by the Spring Security Core plugin:
  grails.plugins.springsecurity.userLookup.userDomainClassName = 'common.auth.User'
  grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'common.auth.UserAuthority'
  grails.plugins.springsecurity.authority.className = 'common.auth.Authority'
  </code></pre>
  
  <p>my login controller >>></p>
  
  <pre><code>    import grails.converters.JSON
  
  import javax.servlet.http.HttpServletResponse
  
  import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
  
  import org.springframework.security.authentication.AccountExpiredException
  import org.springframework.security.authentication.CredentialsExpiredException
  import org.springframework.security.authentication.DisabledException
  import org.springframework.security.authentication.LockedException
  import org.springframework.security.core.context.SecurityContextHolder as SCH
  import org.springframework.security.web.WebAttributes
  import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
  
  class LoginController {
  
      /**
       * Dependency injection for the authenticationTrustResolver.
       */
      def authenticationTrustResolver
  
      /**
       * Dependency injection for the springSecurityService.
       */
      def springSecurityService
  
      /**
       * Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
       */
      def index = {
          if (springSecurityService.isLoggedIn()) {
              redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
          } else {
              redirect action: 'auth', params: params
          }
      }
  
      /**
       * Show the login page.
       */
      def auth = {
  
          def config = SpringSecurityUtils.securityConfig
  
          if (springSecurityService.isLoggedIn()) {
              redirect uri: config.successHandler.defaultTargetUrl
              return
          }
  
          String view = 'auth'
          String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
          render view: view, model: [postUrl: postUrl,
                  rememberMeParameter: config.rememberMe.parameter]
      }
  
      /**
       * The redirect action for Ajax requests.
       */
      def authAjax = {
          response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
          response.sendError HttpServletResponse.SC_UNAUTHORIZED
      }
  
      /**
       * Show denied page.
       */
      def denied = {
          if (springSecurityService.isLoggedIn() &amp;&amp;
                  authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
              // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
              redirect action: 'full', params: params
          }
      }
  
      /**
       * Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
       */
      def full = {
          def config = SpringSecurityUtils.securityConfig
          render view: 'auth', params: params,
                  model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
                          postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
      }
  
      /**
       * Callback after a failed login. Redirects to the auth page with a warning message.
       */
      def authfail = {
  
          def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
          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
          }
      }
  
      /**
       * The Ajax success redirect url.
       */
      def ajaxSuccess = {
          render([success: true, username: springSecurityService.authentication.name] as JSON)
      }
  
      /**
       * The Ajax denied redirect url.
       */
      def ajaxDenied = {
          render([error: 'access denied'] as JSON)
      }
  }
  </code></pre>
  
  <p>my authority.groovy >>></p>
  
  <pre><code>    package common.auth
  
  class Authority {
  
      String authority
  
      static mapping = {
          cache true
      }
  
      static constraints = {
          authority blank: false, unique: true
      }
  }
  </code></pre>
  
  <p>my user domain.groovy where my user will be saved >>></p>
  
  <pre><code>    package common.auth
  
  class User {
  
      transient springSecurityService
      String realname
      String username
      String password
      String designation
      boolean enabled
      boolean accountExpired
      boolean accountLocked
      boolean passwordExpired
  
      static constraints = {
          username blank: false, unique: true
          password blank: false
      }
  
      static mapping = {
          password column: '`password`'
      }
  
      Set&lt;Authority&gt; getAuthorities() {
          UserAuthority.findAllByUser(this).collect { it.authority } as Set
      }
  
      def beforeInsert() {
          encodePassword()
      }
  
      def beforeUpdate() {
          if (isDirty('password')) {
              encodePassword()
          }
      }
  
      protected void encodePassword() {
          password = springSecurityService.encodePassword(password)
      }
  }
  </code></pre>
  
  <p>my userauthority.groovy >>></p>
  
  <pre><code>    package common.auth
  
  import org.apache.commons.lang.builder.HashCodeBuilder
  
  class UserAuthority implements Serializable {
  
      User user
      Authority authority
  
      boolean equals(other) {
          if (!(other instanceof UserAuthority)) {
              return false
          }
  
          other.user?.id == user?.id &amp;&amp;
              other.authority?.id == authority?.id
      }
  
      int hashCode() {
          def builder = new HashCodeBuilder()
          if (user) builder.append(user.id)
          if (authority) builder.append(authority.id)
          builder.toHashCode()
      }
  
      static UserAuthority get(long userId, long authorityId) {
          find 'from UserAuthority where user.id=:userId and authority.id=:authorityId',
              [userId: userId, authorityId: authorityId]
      }
  
      static UserAuthority create(User user, Authority authority, boolean flush = false) {
          new UserAuthority(user: user, authority: authority).save(flush: flush, insert: true)
      }
  
      static boolean remove(User user, Authority authority, boolean flush = false) {
          UserAuthority instance = UserAuthority.findByUserAndAuthority(user, authority)
          if (!instance) {
              return false
          }
  
          instance.delete(flush: flush)
          true
      }
  
      static void removeAll(User user) {
          executeUpdate 'DELETE FROM UserAuthority WHERE user=:user', [user: user]
      }
  
      static void removeAll(Authority authority) {
          executeUpdate 'DELETE FROM UserAuthority WHERE authority=:authority', [authority: authority]
      }
  
      static mapping = {
          id composite: ['authority', 'user']
          version false
      }
  }
  </code></pre>
  
  <p>And my createUser action to create user in AdministratorActionController >>></p>
  
  <pre><code>    package administrator
  
  import common.auth.User
  
  class AdmistratorActionController {
  
      def springSecurityService
  
      def index() {
             redirect(controller: 'admistratorAction', action: 'createUser')
      }
  
      def createUser = {
                  User user = new User(params)
                  def password = user.password
                  def salt = user.username //depends on what you're using as a salt
                  user.password = springSecurityService.encodePassword(password, salt)
                  user.save()
                  flash.message = "User Create Successfully !!!"
      }
  }
  </code></pre>