如何使用 Spring Security Oauth 保护 Struts2 Rest 服务
Posted
技术标签:
【中文标题】如何使用 Spring Security Oauth 保护 Struts2 Rest 服务【英文标题】:How to securize Struts2 Rest services with Spring Security Oauth 【发布时间】:2015-12-11 19:58:37 【问题描述】:我在配置 spring security Oauth 以在 Struts2 应用程序上使用它来保护其余 Web 服务时遇到了困难。 我已经使用 Spring Security 很长时间了。
如果我很好理解的话,问题是 Spring security Oauth 需要在 root 上设置 spring mvc 调度程序。这和 Struts2 有冲突。
这是我的尝试
2) 根目录上的 Struts2 和 /oauth/* 上的 Spring MVC
<!-- Struts 2 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/struts/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
这对 Oauth 来说没问题,但 Struts2 不再工作了。
1) 根目录上的 Struts2 和 Spring MVC
<!-- Struts 2 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/struts/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/oauth/*</url-pattern>
</servlet-mapping>
Struts2,oauth 正在识别权限,但响应是在 /token 而不是 /oauth/token 上做出的,所以我收到 404 错误。
spring-security.xml的摘录在这里:
<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>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**.api" 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="/api/**.api" access="ROLE_API" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
【问题讨论】:
Ryder,如果您找到了答案,请将其发布给其他人。他们要求它并删除他们的答案。谢谢。当然,你已经一个多月没有登录了,所以没有人屏住呼吸。 【参考方案1】:解决方案是使用 2 个不同的 Spring Dispatchers:
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/oauth/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>rest-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-dispatcher</servlet-name>
<url-pattern>/restapi/*</url-pattern>
</servlet-mapping>
一个用于 Rest WS,另一个用于安全化。
之后,您将把代币赌在 /oauth/token 上,而不是在 /oauth/oauth/token 上
要解决这个问题,你必须复制 Spring Security Parameterization :
<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>
<http pattern="/oauth/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/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>
【讨论】:
以上是关于如何使用 Spring Security Oauth 保护 Struts2 Rest 服务的主要内容,如果未能解决你的问题,请参考以下文章
在没有 servlet api 的 webflux 项目中使用 OAuth2 和 Spring Security OAuth2 和 reactor netty
具有密码授予类型的 WebClient 的 Spring Security OAuth 客户端不要求新令牌
Spring security:Spring security 如何在 SessionRegistry 中注册新会话?
如何使用 Spring Security 模拟身份验证和授权
如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config