【问题标题】:Bearer token is checked even if endpoint is set to permitAll即使端点设置为 permitAll,也会检查承载令牌
【发布时间】:2017-03-15 19:02:25
【问题描述】:

我正在使用 spring-security-oauth2-provider:3.0.0-RC2 和 Grails 3.2.1。所有资源端点都以/api 开头,使用

"/api/$controller/$action?/$id?(.$format)?" {
    constraints {
    }
}

这是过滤器链图(与文档中给出的相同):

String tokenFilters = "JOINED_FILTERS,-oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter"
String securedResourcesFilter = "JOINED_FILTERS,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter"
String otherFilters = "JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter"

grails.plugin.springsecurity.filterChain.chainMap = [
        [pattern: "/api/oauth/token", filters: tokenFilters],
        [pattern: "/api/**", filters: securedResourcesFilter],
        [pattern: "/**", filters: otherFilters]
]

我正在使用密码授予身份验证,只要令牌在浏览器的本地存储中可用,就可以通过传递 Authorization 标头一切正常。

我将不记名令牌存储在浏览器的本地存储中。问题是当令牌过期并且在浏览器的本地存储中仍然可用时。其中一项操作被标记为@Secured(["permitAll"]),因此当我点击该操作时(并且还传递了过期的Authorization 标头),由于令牌已过期,请求被401 拒绝。

这是设计使然,即使端点或控制器/动作设置为permitAll,spring security 仍会检查访问令牌的有效性(如果可用)?

【问题讨论】:

    标签: spring grails spring-security spring-security-oauth2


    【解决方案1】:

    是的,我相信401 响应是设计使然。

    您所描述的是OAuth2AuthenticationProcessingFilter 的行为。过滤器attempts to extract the token from the request 找到一个attempts to authenticate it。如果身份验证由于某种原因(如过期令牌)失败,the filter will treat it as an Authentication failure

    因为OAuth2AuthenticationProcessingFilter 在过滤器链中处于较高位置,它会在请求有机会进入较低级别并根据控制器注释做出决定之前终止无效令牌的请求。

    基本上,如果您提供访问令牌,应用程序将尝试对其进行身份验证。

    解决方法

    当您从 spring-security-oauth2-provider 获取访问令牌时,它通常包含一些过期信息,可以在客户端中检查这些过期信息,以防止首先发送过期的 Authorization 标头。您也可以考虑使用Refresh Token Grant

    如果更改客户端不起作用,您可以配置 filterChain.chainMap,以便您尝试允许的控制器操作的 uri 使用 otherFilters,如下所示:

    grails.plugin.springsecurity.filterChain.chainMap = [
        [pattern: "/api/oauth/token", filters: tokenFilters],
        [pattern: "/api/foo/myControllerActionThatIsPermitAll", filters: otherFilters],
        [pattern: "/api/**", filters: securedResourcesFilter],
        [pattern: "/**", filters: otherFilters]
    ]
    

    请注意,a github issue reported on spring-security-oauth 描述了您的问题。

    【讨论】:

    • 谢谢@Colin。我只是在寻找这个。如果这是默认实现还是有问题,这是我主要关心的问题。
    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 2015-12-30
    相关资源
    最近更新 更多