Oauth 2 + Spring Security - 出现 403 禁止错误

Posted

技术标签:

【中文标题】Oauth 2 + Spring Security - 出现 403 禁止错误【英文标题】:Oauth 2 + Spring Security - Getting 403 Forbidden Error 【发布时间】:2017-11-11 23:21:52 【问题描述】:

我使用 Spring 框架创建了一个简单的 Web 应用程序客户端。我正在使用 OAuth2RestTemplate 调用需要 TLS/SSL 连接的第三方 REST 服务。我已将 Tomcat 配置为使用 HTTPS 端口并指定了我创建的密钥库文件。我还向第三方资源提供商注册了在 Tomcat localhost 上运行的客户端应用程序。我有在我的安全配置 XML 文件中指定的客户端 ID、密码和其他详细信息。我在注册我的网络客户端时选择了“授权码授予类型”。

当我发出请求时,我被重定向到我的 Web 客户端的表单登录。在那里进行身份验证后,我被重定向到第 3 方资源提供者站点以对用户进行身份验证。当我输入用户名和密码时,我会看到需要授权或拒绝请求的页面。在此之后,我收到 403 禁止错误。当我检查第 3 方 REST 服务提供商站点时,我可以看到为我的 POST 请求生成了一个令牌。日志也表明与 Http 代码 200 Ok 相同。但我相信我在使用令牌访问资源时遇到 403 Forbidden 错误,使用我的请求的 Get 调用。

我已经花了很长时间调试和研究这个问题,但到目前为止还没有运气。任何帮助将不胜感激!

这是我的一些代码 sn-ps。

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:oauth2="http://www.springframework.org/schema/security/oauth2"

    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/security/oauth2 
        http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

    <authentication-manager>
        <authentication-provider>
            <user-service>          
                <user name="mm" password="mm" authorities="ROLE_MAIL_USER"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>


    <http pattern="/**">

        <intercept-url pattern="/login.jsp" access="permitAll()" requires-channel="https"/>
        <intercept-url pattern="/css/**" access="permitAll()"  requires-channel="https"/>       
        <intercept-url pattern="/images/**" access="permitAll()"  requires-channel="https"/>        

        <intercept-url pattern="/login" access="permitAll()" requires-channel="https"/>
    <!--    <intercept-url pattern="/**" access="hasRole('ROLE_MAIL_USER')" requires-channel="https"/> -->

        <form-login login-page="/login.jsp"
                    authentication-failure-url="/login.jsp?error=1"
                    login-processing-url="/login"/>

        <logout logout-success-url="/build-newsletter.html"/>

        <csrf/>

    <port-mappings>
        <port-mapping http="8080" https="8443" />
    </port-mappings>

        <custom-filter ref="leg1Filter" after="EXCEPTION_TRANSLATION_FILTER"/>

    </http>

    <oauth2:resource id="tResource" client-id="myclientid"
                                      user-authorization-uri="https://thirdpartyhost/sss/authorize"
                                      access-token-uri="https://thirdpartyhost/oauth2/sss/token"
                                      client-secret="somesecret"
                                      type="authorization_code"
                                      scope="read,write"/>

    <oauth2:rest-template id="tOAuthTemplate" resource="tResource"/>

    <oauth2:client id="leg1Filter"/>

</beans:beans>

我的控制器:

@Controller
public class TAppController 
   
    String endPoint = rest api endpoint;

    @Autowired
    private OAuth2RestTemplate tOAuthTemplate;

        @RequestMapping("/tEventDetails.html")
        public ModelAndView getEventDetails() 
        List<TEventData> tEventData = (List<TEventData>) tOAuthTemplate.getForObject(endPoint + "tEvents", TEvent.class).getData();

    return new ModelAndView("/tDetailsPage.jsp", "tDetails", tEventData);
    
    

重定向到:

以下是日志中的一些 sn-ps:

13:10:34,957 DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:449 - Creating instance of bean 'scopedTarget.org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest#1'
13:10:34,960 DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory:477 - Finished creating instance of bean 'scopedTarget.org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest#1'
13:10:34,968 DEBUG org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider:159 - Retrieving token from *****thirdpartyhost/oauth2/ss/token
13:10:34,982 DEBUG org.springframework.web.client.RestTemplate:78 - Created POST request for "https://thirdpartyhost/ss/super/token"
13:10:34,983 DEBUG org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider:221 - Encoding and sending form: grant_type=[authorization_code], code=[cjtjlstkw7uzt7rvim0xq3ogl], redirect_uri=[****localhost:8443/mm/tDetails.html]
***13:10:35,383 DEBUG org.springframework.web.client.RestTemplate:569 - POST request for "***thirdpartyhost/ss/oauth2/token" resulted in 200 (OK)
13:10:35,403 DEBUG*** org.springframework.web.client.HttpMessageConverterExtractor:92 - Reading [interface org.springframework.security.oauth2.common.OAuth2AccessToken] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@4997b84c]
13:10:35,600 DEBUG org.springframework.security.oauth2.client.OAuth2RestTemplate:78 - Created GET request for "*****thirdpartyhost/v7/ss/me/tEvents?limit=5"
13:10:35,628 DEBUG org.springframework.security.oauth2.client.OAuth2RestTemplate:669 - Setting request Accept header to [application/json, application/*+json]
13:10:35,797  WARN ***org.springframework.security.oauth2.client.OAuth2RestTemplate:581 - GET request for "****thirdpartyhost/v7/ss/tEvents" resulted in 403 (Forbidden); invoking error handler***
13:10:35,804 DEBUG org.springframework.web.client.HttpMessageConverterExtractor:92 - Reading [class org.springframework.security.oauth2.common.exceptions.OAuth2Exception] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@161bd9ce]
13:10:35,806 DEBUG org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver:134 - Resolving exception from handler [com.pvp.webcontrollers.TCERefAppController@4c233b11]: org.springframework.web.client.HttpClientErrorException: 403 Forbidden
13:10:35,807 DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver:134 - Resolving exception from handler [com.pvp.webcontrollers.TCERefAppController@4c233b11]: org.springframework.web.client.HttpClientErrorException: 403 Forbidden
13:10:35,807 DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver:134 - Resolving exception from handler [com.pvp.webcontrollers.TRefAppController@4c233b11]: org.springframework.web.client.HttpClientErrorException: 403 Forbidden
13:10:35,807 DEBUG org.springframework.web.servlet.DispatcherServlet:984 - Could not complete request
org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.security.oauth2.client.http.OAuth2ErrorHandler.handleError(OAuth2ErrorHandler.java:165)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:588)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:546)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)

从日志中我可以看到获取令牌以交换授权码的 POST 请求是成功的。但是在发出 GET 请求以从资源服务器访问资源/数据时出现 403 禁止错误。

【问题讨论】:

【参考方案1】:

我能够解决这个问题。我在服务提供商处注册的客户没有定义正确的类别/组。他们所有的网络服务都按产品领域定义在一个特定的组中。

【讨论】:

你能详细说明一下吗?我面临着类似的问题。 在向其余服务提供商注册客户端时使用正确的设置更相关。还要确保 Web 服务上的域和安全组等安全设置正确,以便客户端调用它。

以上是关于Oauth 2 + Spring Security - 出现 403 禁止错误的主要内容,如果未能解决你的问题,请参考以下文章

spring-security-oauth2中的HttpSecurity配置问题

spring-security-oauth2 - 从资源服务器检查ClientDetails

社交登录,spring-security-oauth2 和 spring-security-jwt?

如何处理 spring-security-oauth2 的版本升级?

为啥spring-security-oauth oauth 2.0实现中需要scope参数

spring-security-oauth2 替代品