基本身份验证过滤器和身份验证输入点实际上未从Spring OAuth2代币请求中使用



我根据Spring的Sparklr示例应用程序和我在网上找到的几个样本实现了带有Spring OAuth2的资源所有者流。我用这样的卷发测试了令牌请求部分,以便提供客户端和用户凭据:

curl -v --data "username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password" -X POST "http://localhost:8080/samplerestspringoauth2/oauth/token"

它可以正常工作,但是我已经进行了以下观察:

尽管根据我看到的示例,我使用了基本授权过滤器,但在安全过程中并未真正使用。由于令牌请求不包含身份验证标头,因此基本授权过滤器只是跳过执行任何检查。ClientCredentialStokenendPointFilter和Authentication-Server是在令牌请求期间唯一执行安全检查的人。注意到这一点并通过调试对其进行验证后,我试图完全删除以下部分:

<http-basic entry-point-ref="clientAuthenticationEntryPoint" />

来自配置。但是后来我得到了警告:

"无法建立Authenticationernaterrypoint。请确保 您有一个通过命名空间配置的登录机构(例如 form-login)或用使用 '入口点ref'属性。

作为下一步,我在HTTP名称空间中添加了入口点ref =" clientauthenticationalticationerpoint,并删除了警告。我测试了应用程序并播放了正确。

但是,除上述内容外,我还在调试期间进行了以下观察:clientcredential -stokenendpointFilter包含私人变量内的OAuthenticationEntrypoint上的入口点,并在由于错误的客户端凭据而失败时使用该点。因此,我在基本过滤器或HTTP名称空间中指定的输入点都无关紧要。最终,客户端crendentystokenendpointFilter将使用其自己的私人oauth2authentication enterrypoint。总结我的结论似乎如下:

  • 如果我们指定基本过滤器,则可以删除基本过滤器http名称空间中的端点。
  • 指定一个基本过滤器或HTTP名称空间中的端点仅适用于编译器停止警告。他们没有实际用途,使用的端点是内部编码的clientcredentialstokenendpointFilter。

下面,我将HTTP和端点配置放置在令牌请求中以供您参考。我跳过其余的配置,以使帖子易于阅读:

<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" />
        <custom-filter ref="clientCredentialsTokenEndpointFilter"
            before="BASIC_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>
<bean id="clientAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <property name="realmName" value="springsec/client" />
        <property name="typeName" value="Basic" />
    </bean>

我还假设在原始Sparklr应用程序(即Spring OAuth2示例应用程序)配置的令牌请求中也发生了相同的问题,这非常相似。可以在https://github.com/spring-projects/spring-security-oauth/blob/master/master/samples/oauth2/sparklr/src/src/main/webapp/webapp/web-inf/spring-spring-spring-spring-spring-spring-spring-spring-sml.xml,和相关部分如下:

<http pattern="/oauth/token" create-session="stateless"
                authentication-manager-ref="clientAuthenticationManager"
                xmlns="http://www.springframework.org/schema/security">
                <intercept-url pattern="/**" method="GET" access="ROLE_DENY" />
                <intercept-url pattern="/**" method="PUT" access="ROLE_DENY" />
                <intercept-url pattern="/**" method="DELETE" access="ROLE_DENY" />
                <intercept-url pattern="/**" 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>

我希望Spring Oauth2能够与Spring Security更加适当地互动,而不必进行不必要和误导性的配置,这使我认为我可能错过了一些东西。由于安全是一个敏感的方面,我想与您分享并询问我的结论是否正确。

/oauth/token提供了两种不同的方法来验证请求令牌的客户端:

  • 使用HTTP-BASIC身份验证(存在" HTTP-BASIC"元素时)

    使用org.springframework.security.web.authentication.www.basicauthentication Filter处理身份验证,并处理"授权" HTTP标头,其中包含base64编码的客户端的凭证。过滤器仅在存在授权标头时执行处理。该方法总是首先尝试。仅当用户提供了带有无效内容的"授权"标头时,HTTP -BASIC上定义的入口点才会被调用 - 这就是为什么您看不到调试器中调用的入口点,尝试设置授权http标头和您的断点将受到打击。

  • 使用client_id和client_secret http paremeters

    在OAuth标准中定义

    这是使用org.springframework.security.oauth2.provider.client.clientcredentystokenendpointFilter进行处理的,默认情况下使用输入点,该输入点将www-authenticate头部发送到客户端。可以自定义默认输入点(有一个setAuthenticationEntrypoint方法)。仅当您提供client_id参数时才使用入口点。

这两种方法都使用不同的方法来获取客户端的用户名 密码,但针对同一身份验证管理器进行验证。

您在取出&lt; http-basic&gt&gt;时观察到的"无法确定authenticationEntryPoint"错误。元素来自弹簧安全本身,而不是来自OAuth扩展。原因是Spring Security无法确定在自定义过滤器客户端centercredentystokenendpointFilter内部已经配置了一个默认的入口点。弹簧安全的HTTP配置始终必须至少具有一个入口点。

因此,完整的逻辑如下:

  • 当您将"授权"标头包含在无效的凭据和&&&&http-basic&gt;存在元素,系统将使用&lt; http-basic&gt&gt;元素。如果未指定任何指定(属性输入点-REF),则系统将自动为您创建basicAuthenticationEntryPoint的默认实例并使用它。
  • 当您使用无效的凭据和自定义过滤器clientcredentystokenendpointFilter中包括HTTP参数" client_id"one_answers" client_secret"时,系统将使用在clientcredentystokenendpointpointfilter bean中定义的切入点
  • 如果"授权"标题和" client_id"参数都不存在,并且端点需要身份验证(" is_authenticatic_ly_ly"),系统将使用在&lt; http entry-entry-refoint-ref ="上定义的输入点。,如果存在,否则将使用HTTP-BASIC上定义的入口点(如上)
  • 如果您没有指定尚未指定http-basic(或弹簧识别的其他默认身份验证方法),也没有使用&lt; http entry-refoint-ref ="&gt; gt; gt; gt;无法建立AuthenticationEntricationEntryPoint",因为它需要至少一个入口点,并且不知道ClientcredentialStokenendPointFilter内部有一个。

关于您的观察:

&gt;&gt;如果我们指定基本过滤器,则可以删除基本过滤器 http名称空间中的端点。

&gt;如果您使用client_id client_secret

对客户端进行身份验证,这是事实。

&gt;&gt;指定基本过滤器或HTTP名称空间中的端点是 仅需要编译器停止警告。他们没有 实际用途,所使用的端点在内部进行了硬编码 clientcredentialstokenendpointFilter。

&gt;部分是正确的,因为在client_id丢失时将使用该入口点。

配置确实令人困惑(这部分是由于Oauth不是Spring Security的本地部分而是扩展的事实引起的),但是所有这些设置都有意义,并且在特定情况下使用。

您所做的更改没有安全性。

最新更新