领先一步
VMware 提供培训和认证,助您加速进步。
了解更多[callout title=2014 年 12 月 11 日更新]虽然最初是关于 Spring Security 4.0.0.M2 的,但博客已更新以反映 Spring Security 4.0 RC1 中发现的改进。[/callout]
以前,应用程序可以使用 Spring Security 在 WebSocket 应用程序中执行身份验证。这是可行的,因为 HttpServletRequest 的 Principal 会传播到 WebSocket Session。
问题在于授权仅限于握手。这意味着一旦连接建立,就无法为 WebSocket 应用程序的授权提供任何粒度。
Spring Security 4.0.0.RC2 通过 Spring Messaging 抽象引入了对 WebSockets 的授权支持。要提供授权,只需扩展 AbstractSecurityWebSocketMessageBrokerConfigurer 并配置 MessageSecurityMetadataSourceRegistry。例如
public class WebSocketSecurityConfig extends
AbstractSecurityWebSocketMessageBrokerConfigurer {
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
. simpDestMatchers("/user/queue/errors").permitAll()
. simpDestMatchers("/**").hasRole("ADMIN");
}
}
[callout title=直接 JSR-356 支持]我们曾考虑直接集成 JSR-356。然而,目前这非常困难,因为 JSR-356 级别非常低,目前不提供必要的抽象。[/callout]
这将确保
/user/queue/errors 目的地可以被任何用户访问ROLE_ADMIN 角色的用户访问同样,我们也可以使用 Spring Security XML 命名空间支持来定义上述配置。等效配置是
<websocket-message-broker>
<!-- pattern matches on the destination header -->
<intercept-message pattern="/user/queue/errors" access="permitAll" />
<intercept-message pattern="/**" access="hasRole('ROLE_ADMIN')" />
</websocket-message-broker>
我们也可以将方法安全用于 WebSockets。例如,以下方法只能由具有 ROLE_ADMIN 角色的用户调用
@PreAuthorize("hasRole('ROLE_ADMIN')")
@MessageMapping("/trade")
public void executeTrade(Trade trade, Principal principal) {
您可以在 rwinch/spring-websocket-portfolio 的 security 分支中找到一个完整的授权示例。
虽然这解决了我们的授权问题,但我们仍然缺少一个在通过 WebSockets 发送消息时保持 HttpSession 存活的良好机制。在下一篇文章中,我将详细讨论这些问题是什么以及 Spring Session 如何缓解这些问题。
[callout title=SpringOne 2GX 2014 即将到来]请尽快预订您在达拉斯举行的 SpringOne 的席位,时间为 9 月 8 日至 11 日。这是了解最新动态并提供直接反馈的最佳机会。 从 0 到 Spring Security 4.0 会议将详细介绍如何开始使用 Spring Security,并深入探讨 Spring Security 4 的新功能。当然,还有许多其他 令人兴奋的 Spring 相关讲座![/callout]