Spring Security登录后一直跳转登录页面原因分析

这篇具有很好参考价值的文章主要介绍了Spring Security登录后一直跳转登录页面原因分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

情况一:

引发错误的SpringSecurity配置如下:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class EdenOauthWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // 禁用csrf攻击防护
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                //启用表单身份验证,放行登录有关接口
                .formLogin()
                // 默认/login
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                // 和退出登录有关的直接放行
                .logout()
                // .logoutUrl(authProperty.getLogoutUrl())
                .invalidateHttpSession(false)
        ;
    }
}

1.情况描述:

测试授权码模式,访问地址:http://localhost:9949/oauth/authorize?client_id=eden&response_type=code&scope=server&redirect_uri=http://www.baidu.com。被Security拦截后,重定向到登录页面。输入正确的用户名和密码,仍然回到登录页面,陷入死循环...

登录成功后又跳转回登录界面,Security,java,前端,http

2.源码分析:

先放一张流程图,待会儿会用到。

登录成功后又跳转回登录界面,Security,java,前端,http

2.1.分析流程:

2.1.1.尝试获取授权码

当我们请求地址:http://localhost:9949/oauth/authorize?client_id=eden&response_type=code&scope=server&redirect_uri=http://www.baidu.com获取授权码的时候,因为此时没有登陆,所以会将我们重定向到登录页面/login,在重定向之前还有一个动作就是缓存本次请求。

上面文字描述的其实就是流程图中的1、2、3、4步骤。

登录成功后又跳转回登录界面,Security,java,前端,http

因为我们没有登录,所以抛出AccessDeniedWxception,然后ExceptionTranslationFilter捕获到并由handleSpringSecurityException方法进行处理。debug如下:

登录成功后又跳转回登录界面,Security,java,前端,http

处理过程中会进入sendStartAuthentication方法,有两步操作:

  • 缓存我们发出的请求。

登录成功后又跳转回登录界面,Security,java,前端,http

  • 做异常的处理:异常处理这里我们可以看到,他会把我们重定向到/login。

登录成功后又跳转回登录界面,Security,java,前端,http

放开断点后,浏览器回到登录页面:

登录成功后又跳转回登录界面,Security,java,前端,http

既然如此,那现在我们就先登录。

2.1.2.尝试登录

此处描述的是流程图中的5、6步骤。

登录成功后又跳转回登录界面,Security,java,前端,http

输入正确的用户名和密码,点击登录。我们知道登录成功之后,AbstractAuthenticationProcessingFilter会调用handler做成功后的处理。

protected void successfulAuthentication(HttpServletRequest request,
      HttpServletResponse response, FilterChain chain, Authentication authResult)
      throws IOException, ServletException {
   //省略...
   successHandler.onAuthenticationSuccess(request, response, authResult);
}

最终会调用SavedRequestAwareAuthenticationSuccessHandleronAuthenticationSuccess方法。如下图断点位置所示,他会根据我们当前的请求来获取我们之前缓存的请求,但是此时获取结果为null:

登录成功后又跳转回登录界面,Security,java,前端,http

然后进入到super.onAuthenticationSuccess(request, response, authentication)方法,这个方法里最终把我们重定向到/根路径。

登录成功后又跳转回登录界面,Security,java,前端,http

于是从浏览器上看到我们又回到了登录页面。

登录成功后又跳转回登录界面,Security,java,前端,http

既然我们是因为无法从缓存中拿到之前的请求而导致再次被重定向到登录界面的,那我们就看一下,获取缓存请求是怎么执行的?

3.原因分析

刚才分析过,登陆成功后,执行requestCache.getRequest(request, response),这个方法有两个默认实现。

登录成功后又跳转回登录界面,Security,java,前端,http

而当我们尝试获取验证码时,因为没有登录抛出异常被重定向到登录页面/login之前的那次缓存请求时怎么做的呢?debug如下,他执行的是NullRequestCachesaveRequest方法。

登录成功后又跳转回登录界面,Security,java,前端,http

从源码中我们看到,saveRequest方法是个空实现,什么都不做,也就是根本就没有缓存这次请求;而当你登陆成功后尝试获取请求的时候,getRequest返回的也是null。

登录成功后又跳转回登录界面,Security,java,前端,http

至此,我们晓得了,为什么我们得不到缓存请求,被一直重定向到登录页面,那如何解决呢?

5.解决方案

既然我们是因为session策略,导致使用了NullRequestCache的默认实现,那我们更改一下session策略不就可以了吗?

修改SpringSecurity的配置中的Session策略,去掉关于session策略的配置。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            // 禁用csrf攻击防护
            .csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            //启用表单身份验证,放行登录有关接口
            .formLogin()
            // 默认/login
            .loginProcessingUrl("/login")
            .permitAll()
            .and()
            // 和退出登录有关的直接放行
            .logout()
            // .logoutUrl(authProperty.getLogoutUrl())
            .invalidateHttpSession(false)
    ;
}

5.1.源码分析

5.1.1.尝试获取验证码

访问地址:http://localhost:9949/oauth/authorize?client_id=eden&response_type=code&scope=server&redirect_uri=http://www.baidu.com。在这里我们不再debug其他位置,直接观察如何缓存的请求。debug如下:

登录成功后又跳转回登录界面,Security,java,前端,http

这是我们看到,缓存请求时的默认实现已经换成了HttpSessionRequestCache,他的saveRequest方法里,将此次请求缓存了起来。

登录成功后又跳转回登录界面,Security,java,前端,http

我们知道这次请求,肯定会因为抛出了AccessDeniedException,被重定向到/login登录页面,那我们继续登录。

5.1.2.尝试登录

登录验证成功后,进入认证成功处理流程。此时我们看到获取缓存请求时的默认实现是HttpSessionRequestCache的方法。

登录成功后又跳转回登录界面,Security,java,前端,http

getRequest方法中,我们可以顺利得到上一次请求的地址,并最终被重定向到redirect_uri的地址中去。

登录成功后又跳转回登录界面,Security,java,前端,http

至此,我们就可以顺利得到授权码了。

登录成功后又跳转回登录界面,Security,java,前端,http

情况二:

情况二是转载自大佬一把杀猪刀的一篇文章《Spring Security OAuth2登录后无法跳转获取授权码地址,直接跳转根路径原因详解》,主要是分析由于存在多个RequestCache对象,当资源服务器接管路径的配置不正确时,无法获取正确的RequestCache对象,导致无法得到授权码。情况一分析时所使用的流程图,也出自一把杀猪刀大佬的这篇文章。而且他的博客中也有很多相当精彩的文章。再次表示感谢!文章来源地址https://www.toymoban.com/news/detail-667929.html

到了这里,关于Spring Security登录后一直跳转登录页面原因分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Selenium登录页面点击登录页面没有跳转问题(click()失效)

    对于一般的登录界面的登录按钮用xpath定位元素再点击就可以进入页面,但是如果登录不是一个按钮而是一张图片,这时我们该怎么定位并登录成功呢? 比如下面这个登录,并不是按钮而是一个div,div里面放了图片 一开始我用了xpath定位,但是结果就是不报错也没有跳转到登录

    2024年02月08日
    浏览(48)
  • Spring Security--自动登录

    也就是remember me 在配置链上加一个  然后发送请求时加上:remember-me字段 value值可以为,ture,1,on 我们记住登录后,关掉浏览器再打开,访问一下接口,可以访问,说明记住登录成功了。    因为有的接口可以支持rememberMe认证,有的接口不支持,用上图的方式做区别。 //禁止

    2024年02月08日
    浏览(36)
  • IDEA Android用户登录页面、登录验证、页面跳转演示示例全部源码

    开发工具: IDEA 2022.3.2,未连接数据库。验证用的用户名和密码为内置硬编码 演示程序运行效果:     设计器中的用户登录页面布局:  登录验证容错提示如下: 1,用户名不能为空: 2,密码不能为空:     3,用户名不存在: 4,用户密码错误    5,登录验证成功跳转到用户

    2024年02月11日
    浏览(52)
  • Qt登录注册页面间跳转

    登录界面 注册界面 实现效果 QQ录屏20220917202345 在登录的类中定义一个私有的注册类成员 右键实现跳转的按钮 选择槽函数 槽函数中实现隐藏登录界面显示注册界面 使用connect函数将信号和槽连接 到这里已经实现了登录界面到注册界面的跳转 在登录界面在定义一个接收信号的

    2024年02月11日
    浏览(40)
  • pyQt界面制作(登录+跳转页面)

    首先打开Qt-D esigner,选择Widget,它和Main Window的区别在于:Main Window有工具栏菜单栏状态栏等,而Widget就适合做个简单的登录界面。如下图:   首先如下列图,在这里可以设置标题为登录,然后插入一个logo图片,也可以给字体标题设置大小样式等。 接下来输入框都是用Line Edit,

    2024年01月23日
    浏览(39)
  • Spring-Security实现登录接口

    Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架 Shiro ,它提供了更丰富的功能,社区资源也比Shiro丰富。 具体介绍和入门看springSecurity入门 在实现之前幺要了解一下登录校验的流程以及 SpringSecurity 的原理以及认证流程 1、登录校验流程 2、 SpringSecurity完

    2024年01月18日
    浏览(51)
  • Spring Security登录用户数据获取(4)

    登录成功之后,在后续的业务逻辑中,开发者可能还需要获取登录成功的用户对象,如果不使用任何安全管理框架,那么可以将用户信息保存在HttpSession中,以后需要的时候直接从HttpSession中获取数据。在Spring Security中,用户登录信息本质上还是保存在 HttpSession中,但是为了方

    2024年02月03日
    浏览(51)
  • Spring Security进行登录认证和授权

    用户首次登录提交用户名和密码后spring security 的 UsernamePasswordAuthenticationFilter 把用户名密码封装 Authentication 对象 然后内部调用 ProvideManager 的 authenticate 方法进行认证,然后 ProvideManager 进一步通过内部调用 DaoAuthencationPriovider 的 authenticate 方法进行认证 DaoAuthencationPriovider 通过

    2024年02月11日
    浏览(45)
  • 系列十一、Spring Security登录接口兼容JSON格式登录

            前后端分离中,前端和后端的数据交互通常是JSON格式,而Spring Security的登录接口默认支持的是form-data或者x-www-form-urlencoded的,如下所示: 那么如何让Spring Security的登录接口也支持JSON格式登录呢?请看下文分析 

    2024年01月20日
    浏览(41)
  • spring boot security验证码登录示例

    在spring boot security自定义认证一文,基本给出了一个完整的自定义的用户登录认证的示例,但是未涉及到验证的使用,本文介绍登录的时候如何使用验证码。 本文介绍一个验证码生成工具,比较老的一个库了,仅作demo使用,不太建议生产用了,因为如果你的代码需要进行安全

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包