在Spring OAuth2中,为什么即使我在资源服务器中标记了资源,我的资源仍然不受保护?

一世,

我使用Spring 3.2.11.RELEASE和spring-security-oauth2 v 2.0.7.RELEASE.我想设置一个资源服务器,这样如果客户端使用grant_credentials的授权类型正确地提交了他们的id和secret,他们就可以使用生成的令牌将数据POST到URL.但是,我无法弄清楚如何保护该URL(即使令牌不正确,我也可以POST到该URL).以下是我尝试配置资源服务器的方法

<oauth:resource-server id="resourceServerFilter" entry-point-ref="entry"
    resource-id="writeUrl" token-services-ref="tokenServices" />

<bean id="entry" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/writeUrl" />
</bean>

<oauth:client-details-service id="clientDetails">
    <oauth:client client-id="my-client-with-secret"
        authorized-grant-types="client_credentials" authorities="ROLE_CLIENT"
        scope="read,write" secret="secret" />
</oauth:client-details-service>

但是,正如我所说,将数据发布到“/ writeUrl”,无论我是否有有效的令牌都是成功的,我希望锁定该URL.我怎么做?我的完整OAuth2应用程序上下文配置如下……

<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->
    <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<!-- The OAuth2 protected resources are separated out into their own block 
    so we can deal with authorization and error handling separately. This isn't 
    mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/oauth/(users|clients)/.*" request-matcher="regex"
    create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
    use-expressions="true" xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/oauth/users/([^/].*?)/tokens/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')"
        method="DELETE" />
    <intercept-url pattern="/oauth/users/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')"
        method="GET" />
    <intercept-url pattern="/oauth/clients/.*"
        access="#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')"
        method="GET" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
    <expression-handler ref="oauthWebExpressionHandler" />
</http>

<!-- The OAuth2 protected resources are separated out into their own block 
    so we can deal with authorization and error handling separately. This isn't 
    mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/me/**" create-session="never"
    entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager"
    xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/me" access="ROLE_USER,SCOPE_READ" />
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="sparklr2" />
</bean>

<bean id="clientAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="sparklr2/client" />
    <property name="typeName" value="Basic" />
</bean>

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

<bean id="clientCredentialsTokenEndpointFilter"
    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
    xmlns="http://www.springframework.org/schema/beans">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <bean class="org.springframework.security.access.vote.RoleVoter" />
            <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

<authentication-manager id="clientAuthenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>

<authentication-manager alias="authenticationManager"
    xmlns="http://www.springframework.org/schema/security">
    <authentication-provider>
        <user-service id="userDetailsService">
            <user name="marissa" password="koala" authorities="ROLE_USER" />
            <user name="paul" password="emu" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

<bean id="clientDetailsUserService"
    class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <constructor-arg ref="clientDetails" />
</bean>

<bean id="tokenStore"
    class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
    <constructor-arg ref="dataSource" />
</bean>

<bean id="tokenServices"
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="tokenEnhancer" ref="tokenEnhancer" />
    <property name="supportRefreshToken" value="true" />
    <property name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="tokenEnhancer"
    class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter" />

<bean id="requestFactory"
    class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
    <constructor-arg name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="approvalStore"
    class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
    <property name="tokenStore" ref="tokenStore" />
</bean>

<oauth:authorization-server
    client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password />
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter" entry-point-ref="entry"
    resource-id="writeUrl" token-services-ref="tokenServices" />

<bean id="entry" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <constructor-arg value="/writeUrl" />
</bean>

<oauth:client-details-service id="clientDetails">
    <oauth:client client-id="my-client-with-secret"
        authorized-grant-types="client_credentials" authorities="ROLE_CLIENT"
        scope="read,write" secret="secret" />
</oauth:client-details-service>

<mvc:default-servlet-handler />

<oauth:expression-handler id="oauthExpressionHandler" />

<oauth:web-expression-handler id="oauthWebExpressionHandler" />

解决方法:

资源端点配置中应该有一个intercept-url,访问权限仅限于授权用户(我猜你的url可以匹配以下模式)

   <security:http pattern="/writeUrl/**" 
                  create-session="never" 
                  entry-point-ref="oauthAuthenticationEntryPoint"
                  access-decision-manager-ref="accessDecisionManager">
     <security:anonymous enabled="false" />
     <security:intercept-url pattern="/**"
                             access="IS_AUTHENTICATED_FULLY"/>

     <security:custom-filter ref="resourceServerFilter"
                             before="PRE_AUTH_FILTER" />
     <security:access-denied-handler ref="oauthAccessDeniedHandler" />
   </security:http>
上一篇:阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_08-SpringSecurityOauth2研究-解决swagger-ui无法访问


下一篇:用Spring Cloud OAuth2和JWT保护微服务