简体   繁体   English

使用Spring Security 3.1通过表单登录和HTTP基本安全性来保护相同的RESTful资源

[英]Using Spring Security 3.1 to secure the same RESTful resources with both form-login and http-basic security

I have a java web application running on Tomcat 7. I am using Spring 3.2 with Spring Security 3.1 on the backend, and am exposing an API via RESTful URLs following the /api/** pattern. 我有一个在Tomcat 7上运行的Java Web应用程序。我在后端使用Spring 3.2和Spring Security 3.1,并按照/ api / **模式通过RESTful URL公开API。

The UI for the web application is built using BackboneJS. 使用BackboneJS构建Web应用程序的UI。 I am using Backbone models mapped directly to the RESTful URLS. 我正在使用直接映射到RESTful URL的Backbone模型。

The UI is locked down using form-login authentication, so the user is always redirected to the login screen if they have are not currently authenticated. UI使用表单登录身份验证锁定,因此,如果用户当前未经过身份验证,则始终将其重定向到登录屏幕。

I am now attempting to expose the same RESTful URLs to another external service using http-basic authentication. 我现在正尝试使用HTTP基本身份验证将相同的RESTful URL公开给另一个外部服务。 Unfortunately, when securing the same URL pattern, it seems Spring will not allow me to use more than one filter chain. 不幸的是,当确保相同的URL模式时,Spring似乎不允许我使用多个过滤器链。 Whichever is defined first in the configuration file seems to take precedence. 在配置文件中最先定义的那个优先。

I would hate to have to map to separate URL patterns for the same RESTful resources, but it seems like I may not have a choice. 我讨厌必须为相同的RESTful资源映射到单独的URL模式,但是似乎我没有选择。

Here is the important sample of my (currently broken) spring security configuration: 这是我的(当前已损坏的)spring安全配置的重要示例:

<!--  configure basic http authentication -->
<http pattern="/api/**" create-session="stateless">
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <http-basic/>
</http>

<!--  configure form-login authentication -->
<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/ui/login" access="permitAll" />
    <intercept-url pattern="/ui/logout" access="permitAll" />
    <intercept-url pattern="/ui/loginfailed" access="permitAll" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <custom-filter ref="ajaxTimeoutRedirectFilter" after="EXCEPTION_TRANSLATION_FILTER" />
    <form-login login-page="/ui/login" default-target-url="/" authentication-failure-url="/ui/loginfailed" />
    <logout logout-success-url="/ui/logout" />
    <session-management invalid-session-url="/ui/login"/>
</http>

My question is: Is it possible to configure two different types of security (http-basic and form-login) for the same URL patterns using Spring Security? 我的问题是: 是否可以使用Spring Security为相同的URL模式配置两种不同类型的安全性(http-basic和form-login)? Is there a best practice for this type of scenario? 是否有针对此类情况的最佳实践?

Thank you. 谢谢。

Why don't you just merge the two <http> elements like this: 您为什么不像这样合并两个<http>元素:

<http pattern="/api/**" use-expressions="true">
    <intercept-url pattern="/ui/login" access="permitAll" />
    <intercept-url pattern="/ui/logout" access="permitAll" />
    <intercept-url pattern="/ui/loginfailed" access="permitAll" />
    <intercept-url pattern="/**" access="ROLE_USER" />
    <http-basic/>
    <custom-filter ref="ajaxTimeoutRedirectFilter" after="EXCEPTION_TRANSLATION_FILTER" />
    <form-login login-page="/ui/login" default-target-url="/" authentication-failure-url="/ui/loginfailed" />
    <logout logout-success-url="/ui/logout" />
    <session-management invalid-session-url="/ui/login"/>
</http>

This would set up both a UsernamePasswordAuthenticationFilter and a BasicAuthenticationFilter in the same filter chain which could serve the ui client, and the external service as well. 这将在同一过滤器链中同时设置UsernamePasswordAuthenticationFilterBasicAuthenticationFilter ,可以为ui客户端和外部服务提供服务。

Not possible out of the box to apply 2 different filter chain for a single URL pattern. 开箱即用不可能为单个URL模式应用2个不同的过滤器链。

But it is a advisable to have unique URL patterns as UI and API, as you would have to apply a completely different filter chain in future. 但是建议您使用独特的URL模式(如UI和API),因为将来您必须应用完全不同的过滤器链。

For example the SecurityContextRepository hold the session information and is retrieved for each request. 例如,SecurityContextRepository保留会话信息,并针对每个请求进行检索。 You don't want to apply the same for UI and API access through basic auth 您不想通过基本身份验证将相同的内容应用于UI和API访问

Try to replace pattern="/ " by pattern="/api/ " in API config: 尝试在API配置中将pattern =“ / 替换为pattern =“ / api / ”:

<http pattern="/api/**" create-session="stateless">
    <intercept-url pattern="/api/**" access="ROLE_USER"/>
    <http-basic/>
</http>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM