springsecurity跳转自制登录页面_史上最简单的Spring Security教程(四):成功登录页面...

5c51361cfc3a98946ba20a8147a93912.png

配置

大多数情况下,我们在访问一个系统时,会直接访问我们收藏的某个页面,或者首页,又或者是访问根路径,成功登录系统后,一般情况下,会重定向到这些页面。如果并没有明确的目的指向,或者说我们想要让系统在登录成功后,一直指向某个页面怎么办?

其实,这很简单,很显然,Spring Security 也考虑到了这一点,在原配置基础上,添加一项 defaultSuccessUrl 配置即可。

http.formLogin().loginPage("/login").defaultSuccessUrl("/index").permitAll()

接下来,启动系统,分别用几种情况测试一下。

访问个人中心页面 http://localhost:8080/springsecuritylearning/user/index,登录后,系统跳转到了个人中心页面。

52feb2d060d183893b142db5b2009d7d.png

查看Network标签,也确实是这样。

e8c29d4e71959324dc801507ff086f67.png

重启系统,或者清除浏览器缓存。

访问系统首页 http://localhost:8080/springsecuritylearning/index,系统跳转到了首页。

7daa11d85b91c95cc8a940b463bce6ff.png

查看Network标签,也印证了这点。

接下来,访问系统根路径 http://localhost:8080/springsecuritylearning/,从原理上讲,应该跳转到根路径页面,由于系统配置访问根路径时,重定向到首页,所以,在用户成功登录后,会先重定向到根路径,然后又重定向到首页。

到此,可能还会有疑问,如果我要让系统不管什么情况,不管之前输入的什么地址,在成功登录后,都跳转到各自的个人中心、亦或是首页呢?

这个需求也很常见,比如,做自媒体的应该有感受,我们登录某个自媒体后台后,一般情况下,会直接跳转到后台的个人中心,展示一些统计信息,如粉丝数、收益等等。

Spring Security 也提供了这个配置项。

http.formLogin().loginPage("/login").defaultSuccessUrl("/user/index", true).permitAll()

重启系统后,再次尝试以上的几种情况,我们发现,系统果然会在登录成功后,始终跳转到个人中心页面。

原理剖析

Spring Security 框架在用户成功登录后的处理逻辑,相对来说比较复杂,比较绕,下面我们就关键逻辑,进行相关分析。

首先,框架默认的 AuthenticationSuccessHandler SavedRequestAwareAuthenticationSuccessHandler。

判断当前Request是否缓存(另外需要看 Spring Security 是否开启了 Request 缓存,默认是开启的)。

......
    
SavedRequest savedRequest = requestCache.getRequest(request, response);

if (savedRequest == null) {
    super.onAuthenticationSuccess(request, response, authentication);

    return;
}

......

如果 Spring Security 关闭了 Request 缓存,或者当前 Request 并没有被缓存,那么就走默认的认证成功逻辑

否则,继续根据 alwaysUseDefaultTargetUrl 判断是否永远重定向到 defaultTargetUrl;亦或是,如果配置了targetUrlParameter 且当前 request 存在该参数值,那么,从缓存中移除当前request,并走默认的认证成功逻辑。

......
    
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl()
    || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
    requestCache.removeRequest(request, response);
    super.onAuthenticationSuccess(request, response, authentication);

    return;
}    
    
......    

以上情况都不满足,即 Spring Security 开启了 Request 缓存,且当前 request 被缓存了,框架即重定向到缓存 request 对应的地址

// Use the DefaultSavedRequest URL
String targetUrl = savedRequest.getRedirectUrl();
logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);

默认的认证成功逻辑,也不复杂,就是判断要重定向的地址这个逻辑,比较繁琐。

protected String determineTargetUrl(HttpServletRequest request,
                                    HttpServletResponse response) {
    if (isAlwaysUseDefaultTargetUrl()) {
        return defaultTargetUrl;
    }

    // Check for the parameter and use that if available
    String targetUrl = null;

    if (targetUrlParameter != null) {
        targetUrl = request.getParameter(targetUrlParameter);

        if (StringUtils.hasText(targetUrl)) {
            logger.debug("Found targetUrlParameter in request: " + targetUrl);

            return targetUrl;
        }
    }

    if (useReferer && !StringUtils.hasLength(targetUrl)) {
        targetUrl = request.getHeader("Referer");
        logger.debug("Using Referer header: " + targetUrl);
    }

    if (!StringUtils.hasText(targetUrl)) {
        targetUrl = defaultTargetUrl;
        logger.debug("Using default Url: " + targetUrl);
    }

    return targetUrl;
}

简而言之,就是如果 alwaysUseDefaultTargetUrl 为true,则重定向 defaultTargetUrl;如果配置了 targetUrlParameter 且其对应的值不为空,则重定向到该地址;如果配置的 useReferertrue 且其值不为空,则重定向到该地址;否则,则重定向到 defaultTargetUrl

针对成功登录后的这段复杂逻辑,画了一个流程图,可以参照这些关键代码,加深一下理解。

2ad000ba3b09c94073f98ce25f70c7e5.png

源码

github

liuminglei/SpringSecurityLearning

gitee

luas/SpringSecurityLearning

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年!

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!


文章不定时更新,可微信搜索「银河架构师」,精彩内容,先睹为快!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security中,可以通过配置实现登录成功后的跳转,具体步骤如下: 1. 配置登录页面Spring Security的配置文件中,配置登录页面,例如: ```java @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .permitAll() .and() .logout() .permitAll(); } ``` 这里的`loginPage("/login")`表示登录页面的URL是`/login`,`.defaultSuccessUrl("/home")`表示登录成功跳转到`/home`页面。 2. 配置登录成功处理器 在Spring Security的配置文件中,配置登录成功处理器,例如: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .successHandler(loginSuccessHandler()) // 配置登录成功处理器 .permitAll() .and() .logout() .permitAll(); } @Bean public AuthenticationSuccessHandler loginSuccessHandler(){ return new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.sendRedirect("/home"); // 登录成功跳转到/home页面 } }; } } ``` 这里的`successHandler(loginSuccessHandler())`表示在登录成功后调用一个名为`loginSuccessHandler`的Bean,该Bean是一个实现了`AuthenticationSuccessHandler`接口的类,在其`onAuthenticationSuccess`方法中实现登录成功后的跳转。 以上就是在Spring Security中实现登录成功跳转的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值