Black Dynamite
Black Dynamite

Reputation: 4147

Grails Spring-Security Confustion

I am designing a Single Page Application with a Grails backend. Some of the services on the backend will require authentication, so I am attempting to use the Spring Security plugin along with client-side cookies to manage this.

I've tried everything, but there doesn't seem to be alot of information about creating a Login service that takes a username/password parameter set, and sets the session to authenticated. Here is what I have thus far.

 class LoginService {

  def userDetailsService
  def daoAuthenticationProvider

  def login(String username, String password )
  {
      UserDetails userDetails = userDetailsService.loadUserByUsername(username);
      Authentication authentication = 
        new UsernamePasswordAuthenticationToken(username, password);
      SecurityContextHolder.getContext().setAuthentication(authentication);
      daoAuthenticationProvider.additionalAuthenticationChecks( 
        userDetails, authentication)
      authentication.isAuthenticated()
  }
  }

My incorrect idea is that the UserDetailsService loads an object from the db concerning the username in question. The authentication object is the method I want to use concerning that UserDetail. Then, the daoAuthenticationProvider checks to see if the details and authentication objects jive with each other (checks for a valid password).

Here is my service test whereby both tests fail with "Bad Credentials"

def fixtureLoader
def grailsApplication
def loginService
def loginPerson

def setup() {
    loginPerson = new Person();
    loginPerson.username = "username"
    loginPerson.password = "password"
    loginPerson.email = "email"
    loginPerson.save(flush: true, failOnError: true)
}

def cleanup() {
}

void "test correct login"() {
    when:
    def result = loginService.login(loginPerson.username,loginPerson.password)

    then:
    assert result == true
}

void "test incorrect login"() {
    when:
    def result = loginService.login(loginPerson.username,"computer")

    then:
    assert result == false
}

I'm not really sure what I'm supposed to be doing as far as to the sequence of events in authentication.

Any help is greatly appreciated.

Upvotes: 0

Views: 147

Answers (1)

Bartek Gawel
Bartek Gawel

Reputation: 71

  • Change your login service method to use authenticationManager if you want to log in user manually:

class LoginService {
    def authenticationManager

    def login(String username, String password ) {
        Authentication preAuthentication = new UsernamePasswordAuthenticationToken(username, password)
        def authentication = authenticationManager.authenticate(preAuthentication)
        SecurityContextHolder.getContext().setAuthentication(authentication)
        authentication.isAuthenticated()
    }
}
  • In your integration test "test correct login", pass a string "password" instead of loginPerson.password (in case your password is encrypted)

  • In "test incorrect login", replace 'assert result == false' with 'thrown(BadCredentialsException)' (exception is actually expected here)

Upvotes: 1

Related Questions