【问题标题】:Spring Security: how to authenicate WebSocket with zoneinfoSpring Security:如何使用 zoneinfo 对 WebSocket 进行身份验证
【发布时间】:2017-05-18 05:10:55
【问题描述】:

有人可以建议如何使用 Spring Security 框架保护 Web 套接字端点吗?

我有一个使用 Spring Security 保护的应用程序。 其中一个端点是 Web 套接字。 在 Web 套接字处理程序中,我需要对连接到 Web 套接字的用户进行身份验证。 具体来说,我需要同时获取用户 ID 和区域/租户 ID。

如果我在 spring-security.xml 中使用标签 sec:http 作为 websocket 端点(请参阅下面的文件),这会触发登录,然后在 web socket 的 @onOpen (会话会话) 处理程序 当我调用 session.getUserPrincipal() 时,返回的主体里面有一个正确的用户名。

不过,我还需要区域/租户 ID 信息。

我正在尝试使用应该包含它的 SecurityContextHolder.getContext().getAuthentication(),但调用返回 null。 显然,sec:http 不会导致为 Web 套接字请求创建 Authentication 对象。

我被推荐了

http://docs.spring.io/autorepo/docs/spring-security/4.1.x/reference/html/websocket.html

http://docs.spring.io/autorepo/docs/spring-security/4.1.x/reference/html/appendix-namespace.html#nsa-websocket-security

这似乎建议要为 websocket 端点获取带有区域信息的身份验证器,我需要将以下部分添加到 spring-security.xml:

<sec:websocket-message-broker>
    <sec:intercept-message pattern="/WebSocket.svc" access="isAuthenticated()" />
</sec:websocket-message-broker>

然而,当我添加它并尝试启动应用程序时,它会失败并显示以下回溯/消息:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Security namespace does not support decoration of element [websocket-message-broker]
Offending resource: ServletContext resource [/WEB-INF/spring-security.xml]
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.fatal(FailFastProblemReporter.java:60) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:68) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:55) ~[spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.security.config.SecurityNamespaceHandler.reportUnsupportedNodeType(SecurityNamespaceHandler.java:144) ~[spring-security-config-4.1.2.RELEASE.jar:4.1.2.RELEASE]

我正在使用 Spring Security 4.1.2 和 4.3.1 作为主 Spring。

从 Spring 文档中也不清楚 sec:websocket-message-brokersec:http 是否应该与 Web 套接字端点一起使用或相互排斥.

感谢您的建议。

谢尔盖

附:我的 spring-security.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2
        http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-4.1.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

    <sec:http pattern="/Consumer.svc/**" create-session="never"
        entry-point-ref="oauthAuthenticationEntryPoint"
        access-decision-manager-ref="accessDecisionManager"
        authentication-manager-ref="authenticationManager"
        use-expressions="true">
        <sec:anonymous enabled="false" />
        <sec:intercept-url pattern="/Consumer.svc/**" access="isAuthenticated()" />
        <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    </sec:http>

    <sec:http pattern="/WebSocket.svc" create-session="never"
        entry-point-ref="oauthAuthenticationEntryPoint"
        access-decision-manager-ref="accessDecisionManager"
        authentication-manager-ref="authenticationManager"
        use-expressions="true">
        <sec:anonymous enabled="false" />
        <sec:intercept-url pattern="/WebSocket.svc" access="isAuthenticated()"  />
        <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    </sec:http>

    <sec:websocket-message-broker>
        <sec:intercept-message pattern="/WebSocket.svc" access="isAuthenticated()" />
    </sec:websocket-message-broker>

    <bean id="oauthAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    </bean>

    <bean id="oauthWebExpressionHandler"
        class="org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler">
    </bean>

    <bean id="accessDecisionManager"
        class="org.springframework.security.access.vote.UnanimousBased">
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
                    <property name="expressionHandler" ref="oauthWebExpressionHandler" />
                </bean>
                <bean class="org.springframework.security.access.vote.AuthenticatedVoter"  />
            </list>
        </constructor-arg>
    </bean>

    <sec:authentication-manager alias="authenticationManager"/>

    <oauth:resource-server id="resourceServerFilter"
        resource-id="springsec" token-services-ref="offlineTokenServices" />

    <bean id="oauthAccessDeniedHandler"
        class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

    <!-- ... also some other elements here ... -->

</beans>

【问题讨论】:

    标签: spring-security jwt


    【解决方案1】:

    需要在 pom.xml 中添加以下内容:

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-messaging</artifactId>
            <version>4.1.2.RELEASE</version>
        </dependency>
    
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>
    

    这是 spring-security.xml:

    <bean id="springSecurityMessagePathMatcher"    
    class="org.springframework.util.AntPathMatcher"/>
    

    现在 Spring 在启动时不会抛出异常并且可以很好地解析 spring-security.xml,但它也不起作用。 SecurityContextHolder.getContext().getAuthentication() 仍然返回 null。

    【讨论】:

      猜你喜欢
      • 2021-04-29
      • 1970-01-01
      • 2012-11-27
      • 2020-04-16
      • 1970-01-01
      • 2015-11-22
      • 2011-10-17
      • 2018-08-09
      相关资源
      最近更新 更多