[PLUGIN ACEGI] username é case sensitive
06/11/2011 11:32
0
Bom dia pessoal,

Estou usando o plugin acegi e cadastro o usuário com o username em maiúsculo e tento me logar com o username em minúsculo e ele não acha o usuário.

Se eu me logar com username em maiúsculo ele loga.

Toda a base de usuários o username está em maiúsculo, mas o cliente vai logar na aplicação em minúsculo, como que eu transformo o username digitado pelo cliente em minusculo em maiusculo para aplicação achar na base?

Olhei nas classes que o acegi gera, mas não achei em nenhum local aonde ele busca o ussername no banco de dados.

Obrigado
Tags: username é case sensitive


0
Oi Igor,

o Acegi gera um formulário de login pra você que pode ser customizado. Uma solução seria você interceptar as requisições feitas por este formulário usando um filter e, neste, passar o login para maiúscula (ou minúscula se for o caso) para, em seguida, enviar para a action que efetua a autenticação pra você.


0
Oi Henrique, eu tentei fazer isso, mas eu não acho no LoginController aonde ele pega o username digitado na pagina de login e faz a autenticação....

Olha a auth.gsp:
<body>
<div id='login'>
<div class='inner'>
<g:if test='${flash.message}'>
<div class='login_message'>${flash.message}</div>
</g:if>
<div class='fheader'>Please Login..</div>
<form action='${postUrl}' method='POST' id='loginForm' class='cssform'>
<p>
<label for='j_username'>Login ID</label>
<input type='text' class='text_' name='j_username' id='j_username' value='${request.remoteUser}' />
</p>
<p>
<label for='j_password'>Password</label>
<input type='password' class='text_' name='j_password' id='j_password' />
</p>
<p>
<label for='remember_me'>Remember me</label>
<input type='checkbox' class='chk' name='_spring_security_remember_me' id='remember_me'
<g:if test='${hasCookie}'>checked='checked'</g:if> />
</p>
<p>
<input type='submit' value='Login' />
</p>
</form>
</div>
</div>
<script type='text/javascript'>


E o loginController:
import org.codehaus.groovy.grails.plugins.springsecurity.RedirectUtils

import org.grails.plugins.springsecurity.service.AuthenticateService



import org.springframework.security.AuthenticationTrustResolverImpl

import org.springframework.security.DisabledException

import org.springframework.security.context.SecurityContextHolder as SCH

import org.springframework.security.ui.AbstractProcessingFilter

import org.springframework.security.ui.webapp.AuthenticationProcessingFilter



/**

* Login Controller (Example).

*/

class LoginController {



/**

* Dependency injection for the authentication service.

*/

def authenticateService



/**

* Dependency injection for OpenIDConsumer.

*/

def openIDConsumer



/**

* Dependency injection for OpenIDAuthenticationProcessingFilter.

*/

def openIDAuthenticationProcessingFilter


private final authenticationTrustResolver = new AuthenticationTrustResolverImpl()



def index = {

if (isLoggedIn()) {

redirect uri: '/'

}

else {

redirect action: auth, params: params

}

}



/**

* Show the login page.

*/

def auth = {



nocache response



if (isLoggedIn()) {

redirect uri: '/'

return

}



String view

String postUrl

def config = authenticateService.securityConfig.security

if (config.useOpenId) {

view = 'openIdAuth'

postUrl = "${request.contextPath}/login/openIdAuthenticate"

}

else if (config.useFacebook) {

view = 'facebookAuth'

postUrl = "${request.contextPath}${config.facebook.filterProcessesUrl}"

}

else {

view = 'auth'

postUrl = "${request.contextPath}${config.filterProcessesUrl}"

}



render view: view, model: [postUrl: postUrl]

}

/**

* Form submit action to start an OpenID authentication.

*/

def openIdAuthenticate = {

String openID = params['j_username']

try {

String returnToURL = RedirectUtils.buildRedirectUrl(

request, response, openIDAuthenticationProcessingFilter.filterProcessesUrl)

String redirectUrl = openIDConsumer.beginConsumption(request, openID, returnToURL)

redirect url: redirectUrl

}

catch (org.springframework.security.ui.openid.OpenIDConsumerException e) {

log.error "Consumer error: $e.message", e

redirect url: openIDAuthenticationProcessingFilter.authenticationFailureUrl

}

}



// Login page (function|json) for Ajax access.

def authAjax = {

nocache(response)

//this is example:

render """

<script type='text/javascript'>

(function() {

loginForm();

})();

</script>

"""

}



/**

* The Ajax success redirect url.

*/

def ajaxSuccess = {

nocache(response)

render '{success: true}'

}



/**

* Show denied page.

*/

def denied = {

if (isLoggedIn() && 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 = {

render view: 'auth', params: params,

model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication)]

}



// Denial page (data|view|json) for Ajax access.

def deniedAjax = {

//this is example:

render "{error: 'access denied'}"

}



/**

* login failed

*/

def authfail = {



def username = session[AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY]

def msg = ''

def exception = session[AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY]

if (exception) {

if (exception instanceof DisabledException) {

msg = "[$username] is disabled."

}

else {

msg = "[$username] wrong usuario/senha."

}

}



if (isAjax()) {

render "{error: '${msg}'}"

}

else {

flash.message = msg

redirect action: auth, params: params

}

}

/**

* Check if logged in.

*/

private boolean isLoggedIn() {

return authenticateService.isLoggedIn()

}



private boolean isAjax() {

return authenticateService.isAjax(request)

}



/** cache controls */

private void nocache(response) {

response.setHeader('Cache-Control', 'no-cache') // HTTP 1.1

response.addDateHeader('Expires', 0)

response.setDateHeader('max-age', 0)

response.setIntHeader ('Expires', -1) //prevents caching at the proxy server

response.addHeader('cache-Control', 'private') //IE5.x only

}

}

Não consigo entender aonde o controller pega o username digitado no login para transforma-lo em maiusculo.




07/11/2011 11:47


0
Henrique,

Na página auth.gsp o action recebe /bookstore/j_spring_security_check

Mas aonde está isso??

Obrigado
07/11/2011 13:54


0
Oi Igor,

de cabeça assim não me lembro, mas você pode seguir o procedimento abaixo pra descobrir: no diretório de trabalho do Grails (SEU_DIRETORIO_HOME/.grails/[versão do Grails]/projects/[seu projeto]) vá a pasta plugins.

Lá dentro estará presente todo o código fonte do Acegi. O controlador fica no local padrão da pasta plugin, que é o grails-app/controller. Se não me engano, ele tem uma única action.

O caminho do plugin pode variar um pouco em versões mais antigas que o ramo 1.3, mas o procedimento básico é este.


0
Olá Henrique,

Tem somente um controller: AuthBase.groovy

package org.grails.plugins.springsecurity.controller^M

import org.grails.plugins.springsecurity.service.AuthenticateService^M
import org.springframework.security.context.SecurityContextHolder as SCH^M
import org.springframework.web.servlet.support.RequestContextUtils as RCU^M
/**^M
* [Example] Controllers Base class for to use Spring Security (authentication and authorization).^M
class AuthBase {^M
^M
/** Authenticate Service */^M
def authenticateService^M
^M
/** Authenticated user domain instance */^M
def loginUser^M
^M
/** is user logged on or not */^M
boolean logon^M
^M
/** principal */^M
def authPrincipal^M
^M
/** is Admin */^M
boolean isAdmin^M
^M
/** Locale */^M
Locale locale^M
^M
/** main request permission setting */^M
def requestAllowed^M

def beforeInterceptor = {^M
if (requestAllowed != null && !authenticateService.ifAnyGranted(requestAllowed)) {^M
println 'request not allowed: ' + requestAllowed^M
redirect(uri: '/')^M
return^M
}^M
^M
authPrincipal = SCH?.context?.authentication?.principal^M
if (authPrincipal != null && authPrincipal != 'anonymousUser') {^M
loginUser = authPrincipal?.domainClass^M
logon = true^M
isAdmin = authenticateService.ifAnyGranted('ROLE_SUPERVISOR')^M
}^M
^M
/* i18n: if lang params */^M
if (params['lang']) {^M
locale = new Locale(params['lang'])^M
RCU.getLocaleResolver(request).setLocale(request,response,locale)^M
session.lang = params['lang']^M
}^M
/* need this for jetty */^M
if (session.lang != null) {^M
locale = new Locale(session.lang)^M

RCU.getLocaleResolver(request).setLocale(request,response,locale)^M
}^M
if (locale == null) {^M
locale = RCU.getLocale(request)^M
}^M
^M
/* cache */^M
response.setHeader('Cache-Control','no-cache') // HTTP 1.1^M
response.setDateHeader('max-age', 0) ^M
response.setIntHeader ('Expires', -1) //prevents caching at the proxy server ^M
response.addHeader('cache-Control', 'private') //IE5.x only^M
}^M
}^M

******
Eu posso alterar essa classe?

É nessa classe que eu altero para maiúsculo o login?

Seria a variavel loginUser ?

Obrigado,
..

07/11/2011 15:54


0
Oi Igor, não é recomendavel que você altere esta classe. Caso queira, o ideal é que você altere no próprio código fonte do plugin e o reempacote novamente. Lembre-se que qualquer alteração no seu diretório de trabalho do Grails vai ser perdida no primeiro comando "grails clean" que você executar.



0
Olá Henrique,
Não é essa classe que postei, analisei melhor e é na classe GrailsDaoImpl.groovy que precisa da alteração, que é bem simples, colocar o toUpperCase(username.toUpperCase).

Essa classe fica no caminho:
/home/igordami/.grails/1.3.7/projects/bookstore/plugins/acegi-0.5.3.2/src/groovy/org/codehaus/groovy/grails/plugins/springsecurity/GrailsDaoImpl.groovy

Henrique, eu fiz a alteração na classe GrailsDaoImpl.groovy e testei e funcionou.

Mas fiquei com dúvidas que você disse que quando eu der o "grails clean" ele vai perder as alterações que eu fiz. Vou perder o que eu fiz na classe GrailsDaoImpl.groovy?

Se não for perder as alterações, tudo bem, mas se for perder as alterações, por favor, me explique como eu faço para reempacotar o novamente?

Obrigado
07/11/2011 18:28


0
Henrique,

Uma dúvida:

Executando o grails clean, ele limpa os diretórios e arquivo abaixo:

[delete] Deleting: /home/igordami/.grails/1.3.7/projects/bookstore/resources/web.xml
[delete] Deleting directory /home/igordami/ldap_teste/bookstore/target/classes
[delete] Deleting directory /home/igordami/.grails/1.3.7/projects/bookstore/plugin-classes
[delete] Deleting directory /home/igordami/.grails/1.3.7/projects/bookstore/resources

Mas a classe GrailsDaoImpl.groovy que alterei, não fica no caminho que foi limpado:

/home/igordami/.grails/1.3.7/projects/bookstore/plugins/acegi-0.5.3.2/src/groovy/org/codehaus/groovy/grails/plugins/springsecurity/GrailsDaoImpl.groovy

Quando eu gerar o pacote .war da aplicação, ele vai levar essa alteração que fiz na classe GrailsDaoImpl.groovy?


Obrigado,
07/11/2011 18:39


0
Oi Igor, neste caso, ele irá levar para o war.

Mas eu não recomendo de modo algum você alterar o código fonte do plugin que se encontra nesta pasta, pois é conteúdo volátil.

Minha sugestão é a seguinte: se for para de fato alterar o plugin, você deve seguir o seguinte procedimento.

1. Baixe o código fonte do plugin e altere-o em um diretório qualquer
2. Feita a edição, execute o comando grails package-plugin. Ele vai gerar um arquivo .zip se não me engano
3. Instale o plugin alterado na sua aplicação com o comando grails install-plugin [caminho pro .zip]

Assim você não vai perder o seu código fonte alterado caso seu workdir seja apagado.


0
Oi Henrique,
Fiz isso que você falou.
Baixei o código fonte, alterei, gerei o pacote do plugin e instalei ele na aplicação.

Funcionou bem.

Muito obrigado pela ajuda.

Abs
08/11/2011 12:48



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto