我一直在努力使用 Spring-Security 正确实施 Stomp (websocket) 身份验证 和 授权。 对于后代,我将回答我自己的问题以提供指导。
问题
Spring WebSocket 文档(用于身份验证)看起来不清楚 ATM(恕我直言)。而且我无法理解如何正确处理 Authentication 和 Authorization 。
我想要的是
- 使用登录名/密码对用户进行身份验证。
- 防止匿名用户通过 WebSocket 连接。
- 添加授权层(用户、管理员……)。
- 在控制器中有
Principal
可用。
我不想要什么
- 在 HTTP 协商端点上进行身份验证(因为大多数 JavaScript 库不会随 HTTP 协商调用一起发送身份验证标头)。
原文由 Anthony Raymond 发布,翻译遵循 CC BY-SA 4.0 许可协议
如上所述,文档看起来不清楚(恕我直言),在 Spring 提供一些清晰的文档之前,这是一个样板文件,可以让您免于花两天时间试图了解安全链在做什么。
Rob-Leggett 做了一个非常好的尝试,但是,他正在 分叉一些 Springs 类,我觉得这样做不舒服。
开始前须知:
AuthenticationProvider
完全不参与 Websocket 身份验证。simpUser
) 将被存储在 websocket 会话中,并且不再需要对进一步的消息进行身份验证。Maven 部门
WebSocket 配置
下面的配置注册了一个简单的消息代理(我们稍后将保护的一个简单端点)。
弹簧安全配置
由于 Stomp 协议依赖于第一个 HTTP 请求,我们需要授权对我们的 stomp 握手端点的 HTTP 调用。
然后,我们将创建一个负责对用户进行身份验证的服务。
请注意:
UsernamePasswordAuthenticationToken
必须 至少有一个 GrantedAuthority,如果您使用另一个构造函数,Spring 将自动设置isAuthenticated = false
。几乎到此为止,现在我们需要创建一个拦截器,它将设置 `simpUser` 标头或在 CONNECT 消息上抛出 `AuthenticationException`。
请注意:
preSend()
必须 返回一个UsernamePasswordAuthenticationToken
,spring 安全链中的另一个元素对此进行测试。请注意:如果您的UsernamePasswordAuthenticationToken
是在未通过GrantedAuthority
的情况下构建的,则身份验证将失败,因为没有授予权限的构造函数自动设置authenticated = false
ISPORTANT没有记录在 spring-security 中。最后再创建两个类来分别处理授权和身份验证。
请注意:
@Order
是至关重要 的不要忘记它,它允许我们的拦截器在安全链中首先注册。