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

时间:2019-01-10 22:12:54

标签: java spring-security spring-security-oauth2

我想知道是否可以在OAuth登录过程中将Spring Security配置为使用外部托管的登录页面。没关系,这不是一个好主意,并且违反了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网址。

进一步研究这一点,我发现向oauth/authorize发出第一个请求时,带有参数的完整url被保存在会话(HttpSessionRequestCache.saveRequest(...)中。

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

1 个答案:

答案 0 :(得分:1)

问题根本不是Spring Security引起的。就是使用Angular SPA。在从Angular应用程序进行跨域POST回/ login时,我需要发送JSESSION_ID cookie。

为此,我创建了一个HttpInterceptoras 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请求。