请先阅读《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中的keyredirect-uri:跳转地址,这个地址必须与做事认证那里配置的跳转地址同等。
{baseUrl}系统会自动更换你当前做事的地址及端口,{registrationId} 会被更换成auth2。
默认情形下系统只能处理/login/oauth2/code/ 地址,当登录成功后跳转回来这个地址时由OAuth2LoginAuthenticationFilter过滤器进行处理。
部分源码如下:

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

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配置

@Configurationpublic 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);

保存OAuth2AuthorizationReques工具到session中

从session获取OAuth2AuthorizationReques工具

设置和获取利用的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.javaOAuth2LoginAuthenticationFilter.java

完毕!


给个关注吧感激

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 动态网关配置

SpringCloud Nacos 整合feign

SpringCloud Nacos 做事消费者