【问题标题】:Configuring resource server with RemoteTokenServices in Spring Security Oauth2在 Spring Security Oauth2 中使用 RemoteTokenServices 配置资源服务器
【发布时间】:2017-03-29 04:47:16
【问题描述】:

我正在尝试使用 spring security oauth2 实现授权服务器和资源服务器。到目前为止,我已经设法设置了授权服务器,并且由于我不想共享 jdbc 令牌存储,因此我正在尝试使用 remoteTokenService 来验证我的令牌@资源服务器。但是每次我尝试访问资源 REST 方法时都会收到 401 错误。

由于项目的性质,我正在使用 xml 配置来设置 spring 安全性。我已经尝试过使用 Javaconfig 的另一个示例项目,它工作正常。

这是我在资源服务器中的配置。

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0" metadata-complete="true">

    <display-name>rest-project</display-name>
    <description>rest project Implementation</description>

    <!--
        - Location of the XML file that defines the root application context.
        - Applied by ContextLoaderListener.
    -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/*.xml</param-value>
    </context-param>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <!--
    - Servlet that dispatches request to registered handlers (Controller implementations).
    -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/mvc-core-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

这是我的 security-config.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
             xmlns:p="http://www.springframework.org/schema/p"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
                        http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">



    <http pattern="/cards/**" use-expressions="true" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint">
        <anonymous enabled="false"/>
        <intercept-url pattern="/cards/**" access="isAuthenticated()" requires-channel="https"/>
        <access-denied-handler ref="oauthAccessDeniedHandler"/>
    </http>

    <oauth2:resource-server id="resourceServerFilter" resource-id="connector-bus" token-services-ref="tokenServices"/>

    <beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.RemoteTokenServices">
        <beans:property name="checkTokenEndpointUrl" value="https://localhost:8443/auth-server/api/oauth/check_token"/>
        <beans:property name="clientId" value="123456" />
        <beans:property name="clientSecret" value="456"/>
    </beans:bean>


    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
                </user-service>
        </authentication-provider>
    </authentication-manager>


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

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

请指出我在这里缺少什么。

提前致谢。

【问题讨论】:

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


    【解决方案1】:

    按照https://stackoverflow.com/a/40626102/3044680 中的说明将您的tokenService 方法设为@Primary,从springboot 1.5 开始,将security.oauth2.resource.filter-order = 3 添加到application.properties

    【讨论】:

      【解决方案2】:

      /oauth/check_token必须单独配置权限,默认为'denyAll'。如果您在属性中添加logging.level.org.springframework.security=DEBUG,您可以找到以下日志记录行:

      2017-09-14 14:52:01.379  INFO 15591 --- [           main] b.a.s.AuthenticationManagerConfiguration : 
      Using default security password: f1f7e508-4a30-4aad-914f-d0e90da6079a
      2017-09-14 14:52:01.775 DEBUG 15591 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'fullyAuthenticated', for Ant [pattern='/oauth/token']
      2017-09-14 14:52:01.872 DEBUG 15591 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'denyAll()', for Ant [pattern='/oauth/token_key']
      2017-09-14 14:52:01.879 DEBUG 15591 --- [           main] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'denyAll()', for Ant [pattern='/oauth/check_token']
      

      我不知道如何在 xml 中允许它,但通过 javaconfig 如下

      @Configuration
      @EnableAuthorizationServer
      public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
          @Override
          public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
              security.checkTokenAccess("isAuthenticated()");
              // security.checkTokenAccess("permitAll");
          }
      }
      

      我找到了How to enable /oauth/check_token with Spring Security Oauth2 using XML。也许有帮助。

      【讨论】:

        【解决方案3】:

        您可以简单地通过属性配置来完成这项工作。尝试将它与 /cards/ URI 的 HttpSecurity 配置一起放入您的 application.yml。

        安全: oauth2: 资源: token-info-uri: https://[你的令牌验证端点] 首选令牌信息:真

        拥有@EnableWebSecurity 和@EnableResourceServer 是重复的。你不需要@EnableWebSecurity。

        【讨论】:

        • 看起来用户使用的不是application.yml文件,配置是在XML中完成的。
        【解决方案4】:

        由于某种原因,我无法让 xml 配置工作以远程验证访问令牌。但是我能够使用 java config 设置 oauth2 资源服务器,它解决了这个问题。请在下面找到代码。

        @Configuration
        @EnableWebSecurity
        @EnableResourceServer
        public class Oauth2ResesourceServerConfiguration  extends ResourceServerConfigurerAdapter{
        
        
            @Override
            public void configure(HttpSecurity http) throws Exception {
                 http.authorizeRequests()
                        .antMatchers(HttpMethod.GET,"/api/**").access("#oauth2.hasScope('read')");
            }
        
            @Primary
            @Bean
            public RemoteTokenServices tokenService() {
                RemoteTokenServices tokenService = new RemoteTokenServices();
                tokenService.setCheckTokenEndpointUrl(
                        "https://localhost:8443/auth-server/oauth/check_token");
                tokenService.setClientId("client-id");
                tokenService.setClientSecret("client-secret");
                return tokenService;
            }
        
        
        
        }
        

        【讨论】:

        • 你知道如果我们有很多客户,“tokenService()”方法会是什么样子吗?
        猜你喜欢
        • 2017-03-25
        • 2013-12-21
        • 2017-02-13
        • 2019-11-27
        • 2016-01-18
        • 2017-09-13
        • 2016-04-27
        • 2018-08-17
        • 2017-12-15
        相关资源
        最近更新 更多