Spring Security OAuth2 使用外部登录页面登录

Posted

技术标签:

【中文标题】Spring Security OAuth2 使用外部登录页面登录【英文标题】:Spring Security OAuth2 Login using External Login Page 【发布时间】:2019-06-05 20:27:28 【问题描述】:

我想知道是否可以将 Spring Security 配置为在 OAuth 登录过程中使用外部托管的登录页面。没关系,这不是一个好主意,并且违背了 OAuth 的目的之一(将登录/凭据/身份验证问题与客户端和资源服务器分开)。

我有以下设置:

客户端 SPA 应用程序,我要使用的登录页面所在的位置 OAuth 身份验证服务器(使用 Spring Security OAuth / @EnableAuthorizationServer) 一个或多个 OAuth 资源服务器

我寻求的 OAuth 流程如下:

用户尝试访问 SPA 中的安全路由 客户端将用户重定向到 OAuth 服务器的授权页面(参数包括状态、随机数等) OAuth 服务器未检测到令牌并重定向到 SPA 的登录页面 用户登录;发布到登录 url(登录 url 位于 OAuth 服务器上;需要 CORS 配置以允许从 SPA 到 OAuth 服务器的跨域发布) 登录成功; Spring 使用最初存在的参数重定向到最初请求的授权页面 授权重定向到令牌;用户获得令牌; SPA 检测到用户现在拥有令牌并允许访问安全路由

我可以配置 Spring Security 以指定一个绝对 URL,以便重定向到我的 SPA 的登录页面:

@Override
protected void configure(HttpSecurity http) throws Exception 
    http.cors()
        .and()
        ... config ...
        .and()
        .formLogin()
        .loginPage("http://angular-spa-app/login") 
        .loginProcessingUrl("/login")
        .permitAll();

当我完成此流程时,我看到向oauth/authorize?state=...&nonce=...&etc... 发出的第一个请求,然后重定向到http://angular-spa-app/login。但是当我登录时,Spring 无法检测到它应该重定向回会话中保存的oauth/authorize url。

进一步深入研究,我发现当第一次向oauth/authorize 发出请求时,带有参数的完整网址会保存在会话中(HttpSessionRequestCache.saveRequest(...)

当登录表单提交并且认证成功时,Spring 会尝试检索保存的请求,以便获取重定向 url 作为 302 Location 标头发送。但是当它这样做时,会话为空,因此 Spring 无法检索任何保存的请求。为什么是这样?我是否需要修改 Spring 会话设置才能解决此问题?

【问题讨论】:

【参考方案1】:

问题根本不在于 Spring Security。它与 Angular SPA 一起使用。从 Angular 应用程序将跨域 POST 返回到 /login 时,我需要发送 JSESSION_ID cookie。

为此,我创建了一个HttpInterceptor (as described here):

@Injectable()
export class AuthInterceptor implements HttpInterceptor 
  constructor() 

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    request = request.clone(
      withCredentials: true
    );
    return next.handle(request);
  

withCredentials: true 位是重要部分;这指示浏览器将 cookie 与 XHR 请求一起发送。

【讨论】:

感谢您花时间发布解决方案,因为我遇到了类似的问题。 oAuth 已经够繁琐了,但是添加一个外部登录页面肯定不会让它变得更简单。干杯!

以上是关于Spring Security OAuth2 使用外部登录页面登录的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring-session 和 spring-cloud-security 时,OAuth2ClientContext (spring-security-oauth2) 不会保留在 Redis

针对授权标头的Spring Security OAuth2 CORS问题

使用spring security jwt spring security oauth2权限控制遇到的坑记录

Spring Security 入门(1-3)Spring Security oauth2.0 指南

Spring Security OAuth2 - 如何使用 OAuth2Authentication 对象?

oauth2 spring-security 如果您在请求令牌或代码之前登录