terça-feira, 28 de julho de 2015

Como usar autenticação basic e form em uma aplicação Grails com Spring Security

No Grails é possível usar duas formas de autenticação em uma aplicação. Só é preciso definir um path separado para que o Spring Security possa tratar diferentemente. No meu caso, eu quero que um controller responda a solicitação via autenticação FORM caso venha de um acesso web e responda a solicitação via autenticação BASIC caso seja uma chamada de uma API.

Primeiro temos um controller Grails qualquer. Estou mantendo apenas um action a titulo de exemplo:

@Secured(["hasAnyRole('ROLE_PESSOA','ROLE_ADMIN')"])
@Transactional(readOnly = true)
class PessoaController {

 static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 50, 100)

  def list = quickSearchService.search(domainClass: Pessoa, searchParams: params,
   searchProperties: searchProperties, query: params.q, customCriteria: customCriteria)
  
        respond list, model:[pessoaInstanceCount: list.totalCount]
    }

}

Esse controller já responde tanto a solicitações HTML quanto JSON. Ex.:
Para HTML:
http://localhost:8080/aplicacao/pessoa/index
Para JSON:
http://localhost:8080/aplicacao/pessoa/index.json

Agora vamos precisar que este controller responda em um segundo endereço que, por sua vez, será configurado para usar autenticação BASIC. Para isso, basta herdar do primeiro colocando o novo controller em um namespace e package diferente.

@Secured(["hasAnyRole('ROLE_PESSOA_API','ROLE_ADMIN')"])
class PessoaController extends br.com.lesteti.PessoaController {
    static scaffold = false
    static namespace = "api"
}

Neste momento, o segundo controller tem as mesmas funcionalidades do primeiro porém responde em um outro endereço por causa da definição do namespace e tem acesso por outra role (ROLE_PESSOA_API).
Para HTML:
http://localhost:8080/api/aplicacao/pessoa/index
Para JSON:
http://localhost:8080/api/aplicacao/pessoa/index.json

Agora falta somente configurar o spring security para que os endereços que contenham /api/ sejam seguros com autenticação BASIC. Altere o Config.groovy adicionando os itens abaixo logo depois da sua configuração normal do Spring Security.

grails.plugin.springsecurity.useBasicAuth = true
grails.plugin.springsecurity.basic.realmName = "LTI"
grails.plugin.springsecurity.filterChain.chainMap = [
        '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
        '/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
]

Nenhum comentário:

Postar um comentário