gpt4 book ai didi

java - Spring Security Oauth - 发送 token 请求时需要的基本访问认证

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:25:37 26 4
gpt4 key购买 nike

我在使用 Spring Security OAuth 2.0 时遇到了一个问题。

有 spring-security 的基本配置,取自示例:

<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"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

<http pattern="/path/**" 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="/path/*" access="ROLE_USER" />
<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="path" />
</bean>

<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="path/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>

<bean id="oauthAuthenticationProvider" class="my.package.OAuthAuthenticationProvider" xmlns="http://www.springframework.org/schema/beans" />

<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 ref="oauthAuthenticationProvider" />
</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.InMemoryTokenStore" />

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

<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>

<!-- authorization-server aka AuthorizationServerTokenServices is an interface
that defines everything necessary for token management -->
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<!-- ClientsDeailsService: Entry Point to clients database (given is in
memory implementation) -->
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="the_client"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_USER" scope="read,write,trust" secret="secret" />

<oauth:client client-id="my-trusted-client-with-secret"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="somesecret" authorities="ROLE_USER" />

</oauth:client-details-service>

<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>

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

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

当我的 web.xml 文件看起来像这样时,它就起作用了:

...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
<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>
...
<servlet>
<servlet-name>Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...
<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

但在这种情况下,系统的“旧部分”不起作用。所以我必须更改 Dispatcher Servlet 映射:

<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/somepath/*</url-pattern>
</servlet-mapping>

现在旧部分可以使用,但不能使用 Oauth Spring 安全性。我试过两种 url 模式:

<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/somepath/*</url-pattern>
<url-pattern>/*</url-pattern>
</servlet-mapping>

然后 oauth 起作用,旧部分不起作用。

我又试了一次并改变了:

<http pattern="/somepath/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/somepath/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

现在它是这样工作的:

  1. 我正在访问地址(之前有效):

    https://localhost.server:8443/system/somepath/oauth/token?grant_type=password&client_id=my-trusted-client-with-secret&client_secret=somesecret&username=user&password=pass

  2. Web 浏览器要求输入登录名和密码(基本访问身份验证)。

  3. 我需要在登录字段中输入客户端 ID,在密码字段中输入密码。

  4. 生成对 oauth 的请求,然后调用 my.package.OAuthAuthenticationProvider 中的身份验证方法。

我应该更改什么以避免出现此基本身份验证提示?

最佳答案

servlet 和过滤器映射的问题源于 Spring OAuth 需要一个 DispatcherServlet 用于其 OAuth 相关端点。我建议您将它们放在默认的 servlet 映射 (/) 中,但这取决于您。在任何情况下,您的一站式安全配置是一个 servlet 配置文件,而不是根上下文(因此您需要使用 DispatcherServlet 而不是 ContextLoaderListener 加载它)。这与示例中的相同(您需要 web.xml 中的 servlet init 参数),但是没有什么可以阻止您添加自己的额外 servlet(当然只要映射不冲突)。

认证问题不同。 OAuth2 规范建议/token 端点使用基本身份验证进行保护,因此原则上提示是一件好事,尽管我可以看到您试图避免它。像您这样将 secret 信息放入表单字段并不足以在生产系统中使用,但如果出于某种原因您需要它,您可以使用 ClientCredentialsTokenEndpointFilter(就像您所做的那样)。过滤器不起作用的原因可能是因为您发送的是 GET(而不是 POST),出于安全目的,这比首先使用过滤器更糟糕,但我没有看到设置的标志任何在过滤器中打开 POST-only 验证的地方(尽管我建议你设置它,如果你在任何地方愤怒地使用这个东西)。

您没有显示 2 个 Spring XML 文件,但您的 web.xml 引用了 2 个。我认为问题最终将可追溯到您将它们混淆或 bean 定义在两者之间重复的事实。也许您可以澄清这一点(或者按照上面的建议切换到从 DispatcherServlet 加载单个文件)?

关于java - Spring Security Oauth - 发送 token 请求时需要的基本访问认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21907777/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com