example grails spring-security

example - spring security grails 3.3 1



Grails Spring Security: Al iniciar sesiĆ³n con una URL de destino se salta el flujo de trabajo posterior a la autenticaciĆ³n (2)

1) Sí, porque es un inicio de sesión "a petición".

2) Sí, puede configurarlo para usar siempre el valor predeterminado. El complemento de seguridad de primavera tiene una configuración para " successHandler.alwaysUseDefault ", cambia eso a true, por defecto es falso.

Además, si necesita más detalles, consulte los documentos de primavera para buscar la sección Establecer un destino de entrada posterior predeterminado .

3) Si aún desea crear el bean de sesión del usuario y luego redirigirlo a la URL original, tiene dos opciones: crear el bean en un filtro anterior o exponer los datos necesarios a través de un UserDetailsService personalizado. Personalmente iría por la ruta de un servicio personalizado de detalles.

En mi aplicación de Grails, he personalizado el flujo de trabajo de autorización de publicación escribiendo un controlador de autenticación auth personalizado (en resources.groovy) como se muestra a continuación.

authenticationSuccessHandler (MyAuthSuccessHandler) { def conf = SpringSecurityUtils.securityConfig requestCache = ref(''requestCache'') defaultTargetUrl = conf.successHandler.defaultTargetUrl alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault targetUrlParameter = conf.successHandler.targetUrlParameter useReferer = conf.successHandler.useReferer redirectStrategy = ref(''redirectStrategy'') superAdminUrl = "/admin/processSuperAdminLogin" adminUrl = "/admin/processAdminLogin" userUrl = "/admin/processUserLogin" }

Como puede hacerlo en las últimas tres líneas del cierre anterior, dependiendo de la Función otorgada al Usuario que inicia sesión, la estoy redirigiendo para separar las acciones dentro del AdminController donde se crea y almacena un UserSessionBean personalizado en la sesión.

Funciona bien para un caso de inicio de sesión normal que en mi aplicación es así:

  1. El usuario accede a la aplicación a través de http://localhost:8080/my-app/ O http://localhost:8080/my-app/login/auth
  2. Ella ingresa su identificación de acceso y contraseña válidos y procede.
  3. La aplicación accede internamente a MyAuthSuccessHandler, que redirige a AdminController teniendo en cuenta la función otorgada a este usuario.
  4. El UserSessionBean se crea y almacena en la sesión
  5. El usuario es llevado a la página de inicio de la aplicación

También he escrito un MyUserDetailsService personalizado extendiendo GormUserDetailsService que se accede correctamente en el flujo anterior.

ESCENARIO DE PROBLEMAS
Considere la posibilidad de que un usuario acceda directamente a un recurso protegido (en este caso, el controlador está asegurado con la anotación @Secured ) dentro de la aplicación.

  1. El usuario hace clic en http://localhost:8080/my-app/inbox/index
  2. La aplicación la redirecciona a http://localhost:8080/my-app/login/auth
  3. El usuario ingresa su identificación de inicio de sesión y contraseña válidas
  4. El usuario se dirige a http://localhost:8080/my-app/inbox/index

El MyAuthSuccessHandler se omite por completo en este proceso y, por lo tanto, mi UserSessionBean no se crea, lo que genera errores al seguir utilizándolo en los lugares donde se accede a UserSessionBean .

PREGUNTAS:

  1. En el escenario del problema, ¿omite la aplicación MyAuthSuccessHandler porque hay una URL objetivo a la que redirigir al iniciar sesión?
  2. ¿Podemos forzar que el proceso pase siempre por MyAuthSuccessHandler incluso con la URL objetivo presente?
  3. Si la respuesta a 2 es no, ¿existe alguna alternativa en cuanto a cómo y dónde se puede crear UserSessionBean ?

Puede implementar EventListener personalizado para manejar el proceso posterior a la conexión, sin interrumpir la URL solicitada por el usuario original.

En config.groovy, inserte un elemento de configuración:

grails.plugins.springsecurity.useSecurityEventListener = true

En you resources.groovy, agrega un bean como este:

import com.yourapp.auth.LoginEventListener beans = { loginEventListener(LoginEventListener) }

Y crea un eventListener en src / groovy así:

package com.yourapp.auth import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent import org.springframework.web.context.request.RequestContextHolder as RCH class LoginEventListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> { //deal with successful login void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) { User.withTransaction { def user = User.findByUsername(event.authentication.principal.username) def adminRole = Role.findByAuthority(''ROLE_ADMIN'') def userRole = Role.findByAuthority(''ROLE_USER'') def session = RCH.currentRequestAttributes().session //get httpSession session.user = user if(user.authorities.contains(adminRole)){ processAdminLogin() } else if(user.authorities.contains(userRole)){ processUserLogin() } } } private void processAdminLogin(){ //move admin/processAdminLogin here ..... } private void processUserLogin(){ //move admin/processUserLogin here ..... } }

Hecho.