具有多个登录页面的 Spring 安全性
Posted
技术标签:
【中文标题】具有多个登录页面的 Spring 安全性【英文标题】:Spring security with multiple login pages 【发布时间】:2014-02-08 04:53:34 【问题描述】:我正在使用 Spring 安全性来保护使用用户名和密码登录到应用程序管理部分。但是现在我的客户需要为应用程序客户端部分提供另一个登录屏幕,他们将在其中拥有自己的用户名/密码来登录客户端部分。到目前为止,我已经使用以下 spring-security.xml 设置成功实现了管理部分登录:
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/login"
default-target-url="/admin/dashboard" always-use-default-target="true"
authentication-failure-url="/login/admin?error_msg=wrong username or password" />
<security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
<security:logout logout-success-url="/login"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider
user-service-ref="adminServiceImpl">
</security:authentication-provider>
</security:authentication-manager>
我在网上搜索了很多,试图找到如何添加客户端部分登录屏幕、拦截 URL、安全身份验证提供程序,但找不到任何信息,所以有人可以帮我解决任何问题链接到任何教程/示例,指导如何做到这一点?
谢谢
【问题讨论】:
【参考方案1】:http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url
pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
<intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
<intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/login-success"
authentication-failure-url="/loginError" />
<!-- <session-management invalid-session-url="/login" session-fixation-protection="newSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management> -->
<logout logout-success-url="/login" delete-cookies="JSESSIONID" />
<csrf disabled="true" />
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
</http>
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/mobile/" access="permitAll" />
<intercept-url pattern="/mobile/login" access="permitAll" />
<!-- <intercept-url pattern="/welcome/**" access="permitAll" /> <intercept-url
pattern="/admin*" access="hasRole('ROLE_ADMIN')" /> -->
<intercept-url access="hasRole('ROLE_USER')" pattern="/main*" />
<intercept-url pattern="/main*" access="hasRole('ROLE_USER')" />
<form-login login-page="/mobile/login" default-target-url="/mobile/login-success"
always-use-default-target="true" authentication-failure-url="/mobile/login?error"
username-parameter="username" password-parameter="password" />
<logout delete-cookies="JSESSIONID" logout-success-url="/mobile/login" />
<csrf disabled="true" />
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
这里我需要所有用户通用的两个登录表单。我已经在 spring-security.xml 中配置了上面提到的标签元素。但是它不起作用。请给我一个解决方案
【讨论】:
【参考方案2】:具有多个登录表单的 Spring MVC App 示例项目。
普通/会员/管理员三种页面。 如果您尝试访问会员页面,您将被带到会员登录表单。 如果您尝试访问管理页面,请转到“管理员登录”表单。
https://github.com/eric-mckinley/springmultihttploginforms
使用安全 xml 配置文件中的 ant 正则表达式请求匹配器完成。
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<global-method-security secured-annotations="enabled" />
<http name="member" pattern="/member/*" request-matcher="ant" auto-config="true" use-expressions="false">
<csrf disabled="true"/>
<intercept-url pattern="/member/home" access="ROLE_MEMBER" />
<intercept-url pattern="/member/account" access="ROLE_MEMBER" />
<intercept-url pattern="/member/orders" access="ROLE_MEMBER" />
<form-login login-page="/member-login" always-use-default-target="false"/>
<logout logout-url="/logout" logout-success-url="/home"/>
</http>
<http name="admin" request-matcher="regex" auto-config="true" use-expressions="false">
<csrf disabled="true"/>
<intercept-url pattern="/admin/home" access="ROLE_ADMIN" />
<intercept-url pattern="/admin/users" access="ROLE_ADMIN" />
<form-login login-page="/admin-login" always-use-default-target="false"/>
<logout logout-url="/logout" logout-success-url="/home"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="password" authorities="ROLE_ADMIN" />
<user name="member" password="password" authorities="ROLE_MEMBER" />
<user name="super" password="password" authorities="ROLE_ADMIN,ROLE_MEMBER" />
</user-service>
</authentication-provider>
</authentication-manager>
【讨论】:
【参考方案3】:我将只使用一个security:http
,但注册两个UsernamePasswordLoginFilter
s。
如果两个登录页面属于同一安全领域,则此解决方案将是合适的。 (因此,如果用户登录的登录页面无关紧要)。当然,您仍然可以使用角色来限制不同类型用户对应用程序不同部分的访问。
这个解决方案应该很简单,因为您不需要处理两个security:http
部分。
这样做的主要缺点是:如果未登录用户尝试访问需要登录的页面,您必须决定在两个登录页面中的哪一个被重定向。
【讨论】:
非常感谢您的回复。不幸的是,我正在寻求的是有两个登录页面,每个登录页面在 DB 中都有自己单独的用户表,所以我想我必须遵循两种安全性:http 方法。【参考方案4】:根据Spring Security docs:
从 Spring Security 3.1 开始,现在可以使用多个 http 元素来定义单独的安全过滤器链配置 不同的请求模式。如果模式属性被省略 http 元素,它匹配所有请求。
每个元素在内部 FilterChainProxy 和应该映射到它的 URL 模式中创建一个过滤器链。元素将按照声明的顺序添加,因此必须再次首先声明最具体的模式。
所以,基本上你需要两个 <http>
元素,每个元素都有一个不同的 pattern
属性。
这里有详细教程:https://blog.codecentric.de/en/2012/07/spring-security-two-security-realms-in-one-application/
【讨论】:
以上是关于具有多个登录页面的 Spring 安全性的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security - 获取登录页面时,安全性尝试进行身份验证并返回 401 错误