Springboot整合第三方OAuth2登录详解及避坑

news/2024/11/28 15:54:43/

环境:springboot2.3.10.RELEASE + OAuth2


请先阅读《SpringBoot2 整合OAuth2实现统一认证 》文章,本篇内容是调用之前写的一个OAuth2认证服务。

相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

应用配置

server:servlet:session:timeout: 30m
---
spring:security:oauth2:client:provider:xgpack:authorization-uri: http://localhost:8208/oauth/authorizetoken-uri: http://localhost:8208/oauth/tokenuser-info-uri: http://localhost:8208/users/userinfouser-name-attribute: nameregistration:auth2:provider: xgpackclient-id: 1client-secret: 1authorization-grant-type: authorization_coderedirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
---
logging:level:org.springframework.security: debug

说明:

authorization-uri:你的认证服务地址
token-uri:获取token地址
user-info-uri:获取用户信息地址
user-name-attribute:用户名,在获取用户信息接口返回的json中的key
redirect-uri:跳转地址,这个地址必须与服务认证那里配置的跳转地址一致。{baseUrl}系统会自动替换你当前服务的地址及端口,{registrationId} 会被替换成auth2。默认情况下系统只能处理/login/oauth2/code/* 地址,当登录成功后跳转回来这个地址时由
OAuth2LoginAuthenticationFilter过滤器进行处理。部分源码如下:

public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/oauth2/code/*";private static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";private static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";private ClientRegistrationRepository clientRegistrationRepository;private OAuth2AuthorizedClientRepository authorizedClientRepository;private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository =new HttpSessionOAuth2AuthorizationRequestRepository();public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository,OAuth2AuthorizedClientService authorizedClientService) {this(clientRegistrationRepository, authorizedClientService, DEFAULT_FILTER_PROCESSES_URI);}// ....
}


DEFAULT_FILTER_PROCESSES_URI:默认该过滤器能处理的请求地址。该过滤器的作用就是获取token信息然后交由AuthenticationManager以登录最终用户。

Security配置

@Configuration
public class OAuthConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable() ;http.authorizeRequests().antMatchers("/error", "/webjars/**", "/resources/**", "/index/**").permitAll().anyRequest().authenticated().and().oauth2Login().logout();.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);}
}

这里设置了下session,因为不设置在跟踪源码的时候你会发现session始终为空

Springboot整合第三方OAuth2登录详解及避坑

 

到此配置就完成了,接下来进行测试。

访问测试接口/home

Springboot整合第三方OAuth2登录详解及避坑

 

登录后出现如下错误信息

Springboot整合第三方OAuth2登录详解及避坑

 

这个错误的原因就是从session中无法获取
OAuth2AuthorizationRequest保存的对象。

OAuth2LoginAuthenticationFilter.java

Springboot整合第三方OAuth2登录详解及避坑

 

跟踪源码查看问题出在哪里?

进入
OAuth2LoginAuthenticationFilter类

Springboot整合第三方OAuth2登录详解及避坑

 

进入选中的方法中

Springboot整合第三方OAuth2登录详解及避坑

 

注意这里的


Map<String, OAuth2AuthorizationRequest> authorizationRequests = session == null ? null : (Map<String, OAuth2AuthorizationRequest>) session.getAttribute(this.sessionAttributeName);

这行代码是从session中获取跳转前保存在session中的
OAuth2AuthorizationRequest对象,没有被获取

Springboot整合第三方OAuth2登录详解及避坑

 

Springboot整合第三方OAuth2登录详解及避坑

 

在整个处理流中并不能从session中获取信息
OAuth2AuthorizationRequest信息。那这个对象又是在哪里设置的呢?是由另外一个核心Filter处理的
OAuth2AuthorizationRequestRedirectFilter。

Springboot整合第三方OAuth2登录详解及避坑

 

注意:这里有两次的重定向,首次这里的if肯定是不会进入的,因为该过滤器默认处理的请求地址是/oauth2/authorization

public class OAuth2AuthorizationRequestRedirectFilter extends OncePerRequestFilter {public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization";
}

第一次重定向:

Springboot整合第三方OAuth2登录详解及避坑

 

接着
OAuth2AuthorizationRequestRedirectFilter就能处理该请求,并且进入if语句中进行重定向到认证服务。而设置保存
OAuth2AuthorizationRequest对象到session中就在如下方法中。

this.sendRedirectForAuthorization(request, response, authorizationRequest);

Springboot整合第三方OAuth2登录详解及避坑

保存OAuth2AuthorizationReques对象到session中

Springboot整合第三方OAuth2登录详解及避坑

 

Springboot整合第三方OAuth2登录详解及避坑

从session获取OAuth2AuthorizationReques对象

设置和获取使用的key都是同一个(确保没有错误)

测试session是否真的有东西?我把跳转到认证服务的地址改错,然后请求,接着用另外一个接口打印session中的内容。

Springboot整合第三方OAuth2登录详解及避坑

 

session中是有内容的,接着吧跳转地址改对,再看session中的内容

跳转到登录页面后,不进行登录,接着访问打印session的接口:

Springboot整合第三方OAuth2登录详解及避坑

 

session中已经没有内容了。

证实:session是跳转到了认证服务后就没有了。难道真的是stackoverflow上所说?

Springboot整合第三方OAuth2登录详解及避坑

 

翻译过来就是:

这些错误意味着找不到授权请求.授权请求存储在会话中,因此有些会话未被存储.默认情况下,会话由cookie管理.
所以我认为这可能是因为你在localhost上运行了所有东西,所以第一个cookie由localhost:8080设置来存储授权请求会话数据,&当你登录到localhost:8081时,它会为它的会话设置另一个cookie。(这里经查,cookie同ip不同端口,cookie共享)。

最后来个结果图,能够返回code,有了这个就可以获取token,获取了token就可以获取用户信息,然后将用户信息交由AuthenticationManager管理实现登录。

Springboot整合第三方OAuth2登录详解及避坑

 


解决上面的问题

在c:\windows\System32\drivers\etc\host文件中添加了如下

Springboot整合第三方OAuth2登录详解及避坑

 

让我们的认证服务通过这个域名访问,修改应用配置文件:

spring:security:oauth2:client:provider:xgpack:authorization-uri: http://www.xg.com:8208/oauth/authorizetoken-uri: http://www.xg.com:8208/oauth/tokenuser-info-uri: http://www.xg.com:8208/users/userinfouser-name-attribute: nameregistration:auth2:provider: xgpackclient-id: 1client-secret: 1authorization-grant-type: authorization_coderedirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'

都修改域名形式,这样我们的cookie应该不会被替换了。接下来再次测试,果然成功了。这里的处理流程是:获取token,获取token后调用获取用户信息接口。

1、自动调用获取token的接口

OAuth2LoginAuthenticationProvider.java

Springboot整合第三方OAuth2登录详解及避坑

 

2、通过上一步获取的token再自动调用获取用户信息表

Springboot整合第三方OAuth2登录详解及避坑

 

注意:获取用户信息的接口,你应该只验证token是否合法即可,不要用security再进行拦截了。security应该排除这个接口。接口如下:

@GetMapping("/userinfo")
public Map<String, Object> userinfo(){ Map<String, Object> res = new HashMap<>() ;String token = extractToken() ;OAuth2Authentication auth = tokenService.loadAuthentication(token) ;res.put("name", auth.getName()) ;return res ;
}

整合第三方OAuth2的核心过滤器:

OAuth2AuthorizationRequestRedirectFilter.java
OAuth2LoginAuthenticationFilter.java

完毕!!!

给个关注吧谢谢

Springboot整合第三方OAuth2登录详解及避坑

 

 

SpringBoot2 整合 OAuth2 资源认证(保护)

SpringBoot2 整合OAuth2实现统一认证

SpringBoot2 整合OAuth2自定义登录与授权页面

ThreadPoolExecutor 参数说明

Springboot之Actuator详解

SpringBoot配置HTTPS支持 单向认证

Tomcat配置参数connectionTimeout意义

SpringCloud Hystrix实现资源隔离应用

Spring Boot Security防重登录及在线总数

Springboot Security 基础应用 (1)

Spring Cloud Sentinel 熔断降级

Spring Cloud Nacos 开启权限验证

Spring Cloud Sentinel 流控限流

Spring Cloud Gateway应用详解1之谓词

SpringCloud zuul 动态网关配置


http://www.ppmy.cn/news/245379.html

相关文章

花生壳 Linux arm

安装和使用Linux花生壳服务 一、安装说明&#xff08;以CentOS 5为例&#xff09; 1、安装必要的开发包 [rootlocalhost ~]# yum install gcc gcc-c autoconf automake 2、下载phddns-2.0.2.16556.tar.gz到某一个目录 [rootlocalhost ~]# wget http://download.oray.com/p…

Java求自幂数

题目解释 一个n位自然数等于自身各个数位上数字的n次幂之和&#xff0c;则称此数为自幂数 一位自幂数&#xff1a;独身数: 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;7&#xff0c;8&#xff0c;9 两位自幂数&#xff1a;没有 三位自幂数…

打印指定进程中的数据

本次要实现&#xff0c;指定进程pid&#xff0c;和某个字符串变量的地址&#xff0c;在linux内核中将字符串内容打印出来。测试程序的代码如下&#xff1a; #include <stdio.h> #include <sys/types.h> #include <unistd.h>char* p "hello, can show …

2022年全国大学生数学建模竞赛总结

写在前面&#xff1a;伴随着国赛成绩的公布&#xff0c;2022年数学建模国赛在我的心里终于落下帷幕&#xff0c;难忘的三天三夜的旅程现在想起来依旧让我热泪盈眶&#xff0c;是我在大学里面为数不多的的热血的经历&#xff0c;是青春&#xff0c;是汗水&#xff0c;是拼搏。 虽…

C语言3位~7位水仙花数(加强版)

输出水仙花数。输人一个正整数&#xff08;3≤ n ≤7)&#xff0c;输出所有的n位水仙花数。水仙花数是指一个 n 位正整数&#xff0c;它的各位数字的n次幂之和等于它本身。例如153的各位数字的立方和1^35^33^3153。 附&#xff1a;水仙花数又称阿姆斯特朗数。 三位的水仙花数共…

DAC驱动芯片 GP8201 GP8403

GP8403 通过I2C接口&#xff0c;线性转换成0-5V或0-10V的两路模拟电压输出。 一个I2C接口支持8路GP8202并联&#xff0c;通过三位硬件地址A2/A1/A0选择。 输入信号范围12Bit&#xff0c;0x000-0xFFF 0-5V/0-10V输出电压通过内部数据控制 输入I2C信号高电平&#xff1a;2.7V-…

某项目网络实施中的几个关键点解析

项目背景&#xff1a;某网络项目牵涉到旧网升级新网的改造&#xff0c;新增设备比较多的是JUNIPER EX系列交换机(涉及高中低端)&#xff0c;与原有CISCO 系列交换机融合。 1、新核心EX8208&#xff08;主&#xff09;与旧核心CISCO 6506相连&#xff0c;网络架构如图&#xff1…

六、opengles显示YUV数据

工程文件名为&#xff1a;com.example.threetextureyuv 1、yuv回顾 1&#xff09;yuv的由来 是在保持图片质量的前提下降低图片内存大小提供传输效率&#xff0c;并且传统的BGR格式 对于黑白图片不支持亮度的调节。 Y”表示明亮度&#xff08;Luminance、Luma&#xff09;&…