网站首页 > 博客文章 正文
环境: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/authorize
token-uri: http://localhost:8208/oauth/token
user-info-uri: http://localhost:8208/users/userinfo
user-name-attribute: name
registration:
auth2:
provider: xgpack
client-id: 1
client-secret: 1
authorization-grant-type: authorization_code
redirect-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 {
@Override
protected 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始终为空
到此配置就完成了,接下来进行测试。
访问测试接口/home
登录后出现如下错误信息
这个错误的原因就是从session中无法获取OAuth2AuthorizationRequest保存的对象。
OAuth2LoginAuthenticationFilter.java
跟踪源码查看问题出在哪里?
进入OAuth2LoginAuthenticationFilter类
进入选中的方法中
注意这里的
Map<String, OAuth2AuthorizationRequest> authorizationRequests = session == null ? null : (Map<String, OAuth2AuthorizationRequest>) session.getAttribute(this.sessionAttributeName);
这行代码是从session中获取跳转前保存在session中的OAuth2AuthorizationRequest对象,没有被获取
在整个处理流中并不能从session中获取信息OAuth2AuthorizationRequest信息。那这个对象又是在哪里设置的呢?是由另外一个核心Filter处理的OAuth2AuthorizationRequestRedirectFilter。
注意:这里有两次的重定向,首次这里的if肯定是不会进入的,因为该过滤器默认处理的请求地址是/oauth2/authorization
public class OAuth2AuthorizationRequestRedirectFilter extends OncePerRequestFilter {
public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization";
}
第一次重定向:
接着OAuth2AuthorizationRequestRedirectFilter就能处理该请求,并且进入if语句中进行重定向到认证服务。而设置保存OAuth2AuthorizationRequest对象到session中就在如下方法中。
this.sendRedirectForAuthorization(request, response, authorizationRequest);
设置和获取使用的key都是同一个(确保没有错误)
测试session是否真的有东西?我把跳转到认证服务的地址改错,然后请求,接着用另外一个接口打印session中的内容。
session中是有内容的,接着吧跳转地址改对,再看session中的内容
跳转到登录页面后,不进行登录,接着访问打印session的接口:
session中已经没有内容了。
证实:session是跳转到了认证服务后就没有了。难道真的是stackoverflow上所说?
翻译过来就是:
这些错误意味着找不到授权请求.授权请求存储在会话中,因此有些会话未被存储.默认情况下,会话由cookie管理.
所以我认为这可能是因为你在localhost上运行了所有东西,所以第一个cookie由localhost:8080设置来存储授权请求会话数据,&当你登录到localhost:8081时,它会为它的会话设置另一个cookie。(这里经查,cookie同ip不同端口,cookie共享)。
最后来个结果图,能够返回code,有了这个就可以获取token,获取了token就可以获取用户信息,然后将用户信息交由AuthenticationManager管理实现登录。
解决上面的问题
在c:\windows\System32\drivers\etc\host文件中添加了如下
让我们的认证服务通过这个域名访问,修改应用配置文件:
spring:
security:
oauth2:
client:
provider:
xgpack:
authorization-uri: http://www.xg.com:8208/oauth/authorize
token-uri: http://www.xg.com:8208/oauth/token
user-info-uri: http://www.xg.com:8208/users/userinfo
user-name-attribute: name
registration:
auth2:
provider: xgpack
client-id: 1
client-secret: 1
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
都修改域名形式,这样我们的cookie应该不会被替换了。接下来再次测试,果然成功了。这里的处理流程是:获取token,获取token后调用获取用户信息接口。
1、自动调用获取token的接口
OAuth2LoginAuthenticationProvider.java
2、通过上一步获取的token再自动调用获取用户信息表
注意:获取用户信息的接口,你应该只验证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
完毕!!!
给个关注吧谢谢
SpringBoot2 整合 OAuth2 资源认证(保护)
猜你喜欢
- 2024-12-14 不服不行啊!大牛确实把SpringCloud集成Dubbo给一次性讲透了
- 2024-12-14 SpringBoot + minio + kkfile 实现文件预览
- 2024-12-14 基于Spring Boot 2.2.6实现Rest风格的文件上传&下载APIs-附源码
- 2024-12-14 如何通过SpringBoot 实现一个OAuth2.0的提供者?
- 2024-12-14 springboot2.2.X手册:5分钟用Netty搭建高性能异步WebSocket服务
- 2024-12-14 Spring Boot 3.0 要来了,这个特性真心强
- 2024-12-14 妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 说明白
- 2024-12-14 SpringBoot 3.2:CRaC技术助力启动速度飞跃
- 2024-12-14 拿捏SpringBoot自动配置实战演示
- 2024-12-14 SpringBoot 3.3.5 试用CRaC,启动速度提升3到10倍
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)