spring-security - 当 Auth 服务器重定向到 SSO 代理服务器时,它不知道登录是否成功
问题描述
成功登录到身份验证服务器后,它会将启用 SSO 的代理服务器重定向回,但代理服务器无法识别用户已通过身份验证,因此它会弹出 3rd Party Permission 页面,而不是将用户转发到最初请求的受保护资源。在第三方权限页面上单击接受后,您将被重定向到最初请求的受保护资源。
- GET http://localhost:8085/angular-example/ 302 响应头:位置:http://localhost:8085/angular-example/ 响应头:Set-Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3;路径=/; HttpOnly
- GET http://localhost:8085/login 302 请求 Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3 响应标头:位置:http://localhost:8084/oauth/authorize?client_id=zuul-proxy-example&redirect_uri=http://localhost:8085/登录&response_type=code&state=SdY74y
- GET http://localhost:8084/oauth/authorize?client_id=zuul-proxy-example&redirect_uri=http://localhost:8085/login&response_type=code&state=SdY74y 302 请求标头:Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3 响应标头:位置:http: //localhost:8084/login 响应头:Set-Cookie: SESSION=Zjk5Y2Y5YTEtMjE2OC00MTRkLThmNGUtNGZlODFkOTI4MWNj; 路径=/; 仅http;SameSite=松懈
- GET http://localhost:8084/login 200 请求头:Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3;会话=Zjk5Y2Y5YTEtMjE2OC00MTRkLThmNGUtNGZlODFkOTI4MWNj
- GET http://localhost:8084/oauth/authorize?client_id=zuul-proxy-example&redirect_uri=http://localhost:8085/login&response_type=code&state=SdY74y 200 请求标头:Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3;会话=MmVhODcyMmMtZDc0MS00Njk3LTk4MTktYTg4MmJhYjI4YmQ2
- POST http://localhost:8084/oauth/authorize 请求头:Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3;SESSION=MmVhODcyMmMtZDc0MS00Njk3LTk4MTktYTg4MmJhYjI4YmQ2 响应头:位置:http://localhost:8085/login?code=KjDZ7n&state=SdY74y 响应头:Set-Cookie:SESSION=; 最大年龄=0;到期时间=周四,1970 年 1 月 1 日 00:00:00 GMT;路径=/; 仅http;SameSite=松懈
- GET http://localhost:8085/login?code=KjDZ7n&state=SdY74y 302 请求标头:Cookie:JSESSIONID=15F0789B7182469477E5F713D64A9BF3 响应标头:位置:http://localhost:8085/angular-example/ 响应标头:Set-Cookie:JSESSIONID =C201DF4673C6644D0B62F166481386C3; 路径=/; HttpOnly
- 获取http://localhost:8085/angular-example/ 200
这是一个 Spring Boot 2.1.8.RELEASE Zuul 代理服务器和一个 Spring Boot 2 身份验证服务器,其配置尽可能接近工作的 Spring Boot 1.5.x 身份验证服务器。
设置
- 克隆https://github.com/smitchell/spring-security-5-upgrade_sso-auth-server
- mvn 弹簧启动:运行
- 克隆https://github.com/smitchell/cloud-foundry-angular-example
- mvn 弹簧启动:运行
- 克隆https://github.com/smitchell/cloud-foundry-angular-example
- ng 服务 --baseHref=/angular-example/
重现步骤:
- 导航到http://localhost:8085/angular-example/
- 以“用户”/“密码”身份登录
- 出现第三方认证页面。单击同意。
- 将显示 Angular 主页。
代理服务器
proxy:
permitAll:
matches: /login,/*.js,/favicon.ico,*.map,/*.css,/robots.txt
zuul:
add-proxy-headers: true
sensitiveHeaders: Cookie,Set-Cookie
ignoredPatterns: /**/health/**,/**/mappings/**
ignored-services: "*"
routes:
angular-example:
path: /angular-example/**
url: http://localhost:4200/angular-example/
auth-service:
path: /auth-example/**
url: http://localhost:4202/auth-example
sensitiveHeaders: Authorization
stripPrefix: false
security:
oauth2:
client:
accessTokenUri: http://localhost:8084/oauth/token
userAuthorizationUri: http://localhost:8084/oauth/authorize
clientId: zuul-proxy-example
clientSecret: ####
server:
port: 8085
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/*.css","/*.js","/favicon.ico","/*.map","/robots.txt")
.permitAll()
.anyRequest().authenticated()
.and()
.logout()
.invalidateHttpSession(true).permitAll()
.logoutSuccessUrl("http://localhost:8085/angular-example/")
.and()
.csrf()
.disable();
// @formatter:on
}
授权服务器配置
server:
port: 8084
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
open-in-view: false
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestMatchers()
.antMatchers("/", "/oauth", "/login", "/api/authenticate", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage( "/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.addFilter(new JwtAuthenticationFilter(privateKey, authenticationManager()))
.addFilter(new JwtAuthorizationFilter(privateKey, authenticationManager()));
// @formatter:on
}
底线,我想了解为什么身份验证没有返回相同的状态参数,这阻止了代理服务器知道先前重定向到身份验证服务器是成功的。
这是来自正在运行的 Spring Security 4 身份验证服务器的单点登录:
- GET https://test.[hostname].com/[context path]/ 302 响应头:位置:http://test.[hostname].com/login 响应头:服务器:cloudflare 响应头:set-cookie: __cfduid=dd164391fe59500752e3500ab3de6a23c1569423515; 到期=格林威治标准时间 20 年 9 月 24 日星期四 14:58:35;路径=/; 域=.[主机名].com;仅http;安全的
- GET http://test.[hostname].com/login 301 请求标头:Cookie:JSESSIONID=C0C62552AAE5F7E8A420EEDD1869AA2A;VCAP_ID =b87f667f-ec72-4a1d-6265-5979 响应头:位置:https://test.[hostname].com/login 响应头:服务器:cloudflare
- GET https://test.[hostname].com/login 302 请求标头:Cookie:cfduid=dd164391fe59500752e3500ab3de6a23c1569423515;JSESSIONID=C0C62552AAE5F7E8A420EEDD1869AA2A;__VCAP_ID =b87f667f-ec72-4a1d-6265-5979 响应头:位置:https://auth-service-test-[hostname].cfapps.io/oauth/authorize?client_id=proxy-service&redirect_uri=http://test。 [主机名].com/login&response_type=code&state=N2mPnD
- GET https://auth-service-test-[hostname].cfapps.io/oauth/authorize?client_id=proxy-service&redirect_uri=http://test.[hostname].com/login&response_type=code&state=N2mPnD 302 响应标头:位置:https://auth-service-test-[hostname].cfapps.io/login 响应头:Set-Cookie:SESSION=4d4be900-b461-4a57-b18b-c5e073e04b25;路径=/; 安全的; HttpOnly
- GET https://auth-service-test-[hostname].cfapps.io/login 请求标头:Cookie:SESSION=4d4be900-b461-4a57-b18b-c5e073e04b25
- POST https://auth-service-test-[hostname].cfapps.io/login 200 请求标头:Cookie:SESSION=4d4be900-b461-4a57-b18b-c5e073e04b25 响应标头:位置:https://auth-service- test-[hostname].cfapps.io/oauth/authorize?client_id=proxy-service&redirect_uri=http://test.[hostname].com/login&response_type=code&state=N2mPnD 响应标头:Set-Cookie:SESSION=661f73be-a34a- 4d3a-83d7-c8a8c682d392;路径=/; 安全的; HttpOnly
- GET https://auth-service-test-[hostname].cfapps.io/oauth/authorize?client_id=proxy-service&redirect_uri=http://test.[hostname].com/login&response_type=code&state=N2mPnD 302 请求标头: Cookie:SESSION=661f73be-a34a-4d3a-83d7-c8a8c682d392 响应标头:位置:http://test.[hostname].com/login?code=o8S3fA&state=N2mPnD 响应标头:Set-Cookie:SESSION=; 最大年龄=0;到期时间=周四,1970 年 1 月 1 日 00:00:10 GMT;路径=/; 安全的; HttpOnly
- GET http://test.[hostname].com/login?code=o8S3fA&state=N2mPnD 301 请求标头:Cookie:JSESSIONID=C0C62552AAE5F7E8A420EEDD1869AA2A;VCAP_ID =b87f667f-ec72-4a1d-6265-5979 响应标头:位置:https://test.[hostname].com/login?code=o8S3fA&state=N2mPnD
- GET https://test.[hostname].com/login?code=o8S3fA&state=N2mPnD 302 请求头:cookie:cfduid=dd164391fe59500752e3500ab3de6a23c1569423515;JSESSIONID=C0C62552AAE5F7E8A420EEDD1869AA2A;__VCAP_ID =b87f667f-ec72-4a1d-6265-5979 响应头:set-cookie:JSESSIONID=8B0E676E8BFE337A598BE060EEA76126;路径=/; HttpOnly 响应头:set-cookie: VCAP_ID =b87f667f-ec72-4a1d-6265-5979; 路径=/; HttpOnly
- GET https://test.[主机名].com/[上下文路径]/200
解决方案
可以在代理中进行修复:
auto-approve-scopes: '.*' # <-- Not for production.
-- 或者 -- 在 auth 服务中更改代理服务客户端:
clientDetails.setAutoApproveCsv("true");
推荐阅读
- wordpress - Wordpress:即使在重新安装肯定有效的版本备份后仍重定向到 wp-admin/install.php
- javascript - 使用 removeChild() [Vanilla Javascript] 从父 DOM 中删除特定索引子项
- php - 变量和引号 - 传递给函数时的区别
- javascript - 如何防止组件随着不断增长的视图向上移动
- c# - 使用 PutObjectRequest 写入 S3,同时仍生成流
- javascript - 使用 Web Audio Api AudioWorklet 从音频流中抓取比特并进行 BPM 检测
- xamarin - Xamarin Forms:转换器的多个项目
- javascript - 仅在来自特定页面时创建该链接
- sql - 使用两个标准查找查询中的差异
- c# - ASP NET Web API google 身份验证问题 HTTP 404