Spring Security sessionID 作为令牌配置

Posted

技术标签:

【中文标题】Spring Security sessionID 作为令牌配置【英文标题】:Spring Security sessionID as token configuration 【发布时间】:2018-02-06 08:51:21 【问题描述】:

我正在使用 Spring Security + Spring session 实现登录过程,为需要创建/维护会话的 REST 类后端服务构建登录功能。

我不确定我是否以正确的方式接近解决方案,因为我正在使用自定义端点手动创建会话。也许会话创建需要在授权方法本身中完成?或者也许有一种方法可以让 spring 在后端进行一些请求验证后创建会话?我为此使用了自定义过滤器和提供程序。

此外,对于我当前的配置,我遇到了一个问题,因为后端 API 正在为每个请求创建一个新会话,即使它应该返回 401。

本方案要求如下:

    客户端将登录到第三方身份验证/授权提供商。验证后,提供商将颁发访问令牌。 API 必须通过第三方提供商验证客户端的访问令牌。验证后,API 必须创建一个会话并向客户端返回一个新的令牌(或 sessionID)。 未来对 API 的调用应在标头/cookie 中包含令牌(或 sessionID),以便 API 获取客户端的会话。

这里最大的问题是: 使用与用户会话相关联的基于令牌的身份验证是否有一种通用的方法可以遵循?如果是这样,如果我需要在 spring session 创建 session 之前进行自定义验证,并且还要向这个 session 添加自定义属性呢?

我的代码在这里:https://github.com/munilvc/api-session/tree/master/src/main/java/com/munilvc/poc/security

例如,一些示例执行:

1) 执行自定义登录:

$ curl -X POST http://localhost:8080/app-api/login/createsession -v
> POST /app-api/login/createsession HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200
< x-auth-token: 15a06ce8-5b34-401a-a05f-a0d933926245
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 29 Aug 2017 01:28:24 GMT
<
171"username":"username1"

2) 使用提供的 x-auth-token 调用另一个端点:

注意 x-auth-token 在响应中被刷新。 (意味着创建了一个新会话 - 这是我们想要避免的,当响应为 401 时也会发生这种情况)

$ curl -X GET http://localhost:8080/app-api/accounts/2 -H "x-auth-token:15a06ce8-5b34-401a-a05f-a0d933926245" -v
> GET /app-api/accounts/2 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
> x-auth-token:15a06ce8-5b34-401a-a05f-a0d933926245
>
< HTTP/1.1 200
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< x-auth-token: 42a5db80-e5e1-4127-bd85-e468af4a8fb2
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 29 Aug 2017 01:29:08 GMT
<
870"id":3,"name":"Account 3"

PS:我不确定是否允许我提供指向堆栈溢出代码的链接。如果没有,我也可以在这里粘贴代码。

非常感谢!

【问题讨论】:

【参考方案1】:

根据您的要求,OpenID Connect 可用于对最终用户进行身份验证并授权客户端,然后客户端将收到AccessToken。然后AccessToken 可以用来调用后端API(资源服务器)。

查看sample/guide,了解如何在 Spring Security 5 中针对外部 OAuth 2.0 或 OpenID Connect 提供程序设置登录。这将满足您使用外部提供程序登录应用程序并在 Spring Security 中创建安全会话的要求。

现在您已登录到应用程序并且客户端具有AccessToken,客户端可以在请求(授权标头)中使用该AccessToken 来调用后端API(资源服务器)。应设置资源服务器以验证传入的AccessToken。看看这个sample(master 和jwt-support 分支),了解如何配置资源服务器。

我强烈建议您更加熟悉OAuth 2.0 Authorization Framework 和OpenID Connect Core 1.0。

祝你好运!

【讨论】:

以上是关于Spring Security sessionID 作为令牌配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring+Security+JWT+MyBatisPlus

Spring+Security+JWT+MyBatisPlus

Spring Security 入门(1-13)Spring Security - Session管理

Spring Security和Angular 5

Spring security - 自定义保持活动控制器

Spring Security - 公共页面重定向到使用无效会话 ID 登录