Grails 3.1.9登录后自定义重定向页面问题求助
嘿,我来帮你搞定这个登录跳转的问题,虽然你对Spring Security和SAML不太熟,但一步步拆解其实不难,分两种场景给你说:普通表单登录和SAML单点登录的处理方式。
一、普通表单登录(你的auth.gsp表单场景)
1. 全局默认跳转配置
如果希望所有登录成功后都跳转到同一个固定页面,直接在grails-app/conf/application.groovy里添加Spring Security的配置:
// 设置登录成功后的默认跳转页面 grails.plugin.springsecurity.successHandler.defaultTargetUrl = "/your-target-page" // 开启后,如果用户是被拦截到登录页的,登录后会回到之前访问的页面(优先级比defaultTargetUrl高) grails.plugin.springsecurity.successHandler.useReferer = true
2. 动态传递跳转目标(比如用户访问某个页面被拦截,登录后回到该页面)
在你的auth.gsp表单里,添加一个隐藏字段来传递目标URL。比如当用户访问/secure/profile被拦截,登录页URL会带上?targetUrl=/secure/profile,我们把这个参数塞进表单:
<form action="/login/authenticate" method="POST" id="loginForm" class="cssform" autocomplete="off"> <!-- 你原有的用户名、密码字段 --> <label for="username"><g:message code="security.login.username.label"/></label> <input type="text" id="username" name="username"/> <label for="password"><g:message code="security.login.password.label"/></label> <input type="password" id="password" name="password"/> <!-- 添加隐藏字段传递目标URL --> <g:if test="${params.targetUrl}"> <input type="hidden" name="targetUrl" value="${params.targetUrl}"/> </g:if> <button type="submit"><g:message code="security.login.button"/></button> </form>
然后自定义一个登录成功处理器来读取这个参数:
创建src/main/groovy/com/yourpackage/CustomAuthenticationSuccessHandler.groovy:
import org.springframework.security.core.Authentication import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { @Override protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { // 先从请求里拿targetUrl参数 String targetUrl = request.getParameter("targetUrl") if (targetUrl) { return targetUrl } // 没有的话就用默认逻辑(比如referer或者全局默认页) return super.determineTargetUrl(request, response, authentication) } }
最后在grails-app/conf/spring/resources.groovy里注册这个bean,替换默认的处理器:
import com.yourpackage.CustomAuthenticationSuccessHandler beans = { authenticationSuccessHandler(CustomAuthenticationSuccessHandler) { defaultTargetUrl = "/your-default-target" useReferer = true } }
二、SAML单点登录场景
如果是走SAML的登录流程,得单独处理SAML的登录成功逻辑,因为它有自己的认证处理器:
1. 自定义SAML认证成功处理器
创建src/main/groovy/com/yourpackage/CustomSamlAuthenticationSuccessHandler.groovy:
import org.springframework.security.core.Authentication import org.springframework.security.saml.SAMLCredential import org.springframework.security.saml.SAMLAuthenticationToken import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse class CustomSamlAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { @Override protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { // 先处理SAML的RelayState参数(SAML协议里用来传递跳转目标的字段) if (authentication instanceof SAMLAuthenticationToken) { SAMLCredential credential = authentication.credential String relayState = credential.relayState if (relayState) { return relayState } } // 再处理请求里的targetUrl参数(和普通表单登录逻辑一致) String targetUrl = request.getParameter("targetUrl") if (targetUrl) { return targetUrl } // 最后用默认逻辑 return super.determineTargetUrl(request, response, authentication) } }
2. 注册自定义SAML处理器
在grails-app/conf/spring/resources.groovy里替换默认的SAML成功处理器:
import com.yourpackage.CustomSamlAuthenticationSuccessHandler beans = { samlAuthenticationSuccessHandler(CustomSamlAuthenticationSuccessHandler) { defaultTargetUrl = "/your-saml-default-target" useReferer = true } }
这样不管是普通表单登录还是SAML登录,都能按照你的需求跳转到指定页面啦~
内容的提问来源于stack exchange,提问作者Jack_Russell

