如何允许用户使用 Spring Security 进行覆盖?
在我的 Spring MVC Web 应用程序中,某些区域只能由具有足够权限的用户访问。我需要能够允许用户以不同用户身份登录才能使用这些页面(有点像覆盖),而不仅仅是显示“访问被拒绝”消息。
我该如何使用 Spring Security 来做到这一点?
这是我想要的流程,更详细一些:
- 用户 A 从外部应用程序进入页面 X 并通过标头进行身份验证
- 用户 A 没有使用页面 X 的权限,因此被带到登录屏幕一条消息,表明他们必须以具有足够权限的用户身份登录才能使用此页面
- 用户 B 登录,并具有足够的权限,并被带到页面 X。
注意:页面 X 有一个又大又长的查询字符串,需要保存下来。
我该如何使用 Spring Security 来做到这一点?
这是我的 spring security 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<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-3.1.xsd">
<debug />
<global-method-security pre-post-annotations="enabled">
<!-- AspectJ pointcut expression that locates our "post" method and applies
security that way <protect-pointcut expression="execution(* bigbank.*Service.post*(..))"
access="ROLE_TELLER"/> -->
</global-method-security>
<!-- Allow anyone to get the static resources and the login page by not applying the security filter chain -->
<http pattern="/resources/**" security="none" />
<http pattern="/css/**" security="none" />
<http pattern="/img/**" security="none" />
<http pattern="/js/**" security="none" />
<!-- Lock everything down -->
<http
auto-config="true"
use-expressions="true"
disable-url-rewriting="true">
<!-- Define the URL access rules -->
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/about/**" access="permitAll and !hasRole('blocked')" />
<intercept-url pattern="/users/**" access="hasRole('user')" />
<intercept-url pattern="/reviews/new**" access="hasRole('reviewer')" />
<intercept-url pattern="/**" access="hasRole('user')" />
<form-login
login-page="/login" />
<logout logout-url="/logout" />
<access-denied-handler error-page="/login?reason=accessDenied"/>
<!-- Limit the number of sessions a user can have to only 1 -->
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
</http>
<authentication-manager>
<authentication-provider ref="adAuthenticationProvider" />
<authentication-provider>
<user-service>
<user name="superadmin" password="superadminpassword" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="adAuthenticationProvider" class="[REDACTED Package].NestedGroupActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="[REDACTED FQDN]" />
<beans:constructor-arg value="[REDACTED LDAP URL]" />
<beans:property name="convertSubErrorCodesToExceptions" value="true" />
<beans:property name="[REDACTED Group Sub-Tree DN]" />
<beans:property name="userDetailsContextMapper" ref="peerReviewLdapUserDetailsMapper" />
</beans:bean>
<beans:bean id="peerReviewLdapUserDetailsMapper" class="[REDACTED Package].PeerReviewLdapUserDetailsMapper">
<beans:constructor-arg ref="UserDAO" />
</beans:bean>
</beans:beans>
我使用的是 Spring Security 3.1 Active Directory 连接功能的稍微修改版本。这些修改只是加载用户的所有组,包括通过组嵌套到达的组,而不仅仅是用户直接所属的组。我还使用一个自定义用户对象,其中嵌入了我的应用程序的用户对象,以及一个自定义 LDAP 映射器,该映射器执行正常的 LDAP 映射,然后添加我的用户。
有一种尚未实现的特殊身份验证方案,其中用户根据从外部应用程序(或通过 Kerberos)以单点登录方式传递的用户名进行身份验证。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如何检查角色?
如果您在安全上下文中像这样定义它们:
您可以在您的 defaultFailureUrl。 x/apidocs/org/springframework/security/web/authentication/SimpleUrlAuthenticationFailureHandler.html" rel="nofollow">
SimpleUrlAuthenticationFailureHandler
并且当用户使用如果权限较低,则尝试访问安全 URL,FaliureHandler
应将您重定向到defaultFailureUrl
,这可能是您的登录页面。您可以在 在
FORM_LOGIN_FILTER
位置过滤。在评论中回答1)。
考虑到您的命名空间配置,这比我想象的要多一些工作。
您需要做的是删除
元素)。
定义,并添加一个“自定义”UsernamePasswordAuthenticationFilter
(这是处理您还需要删除
。所以你的配置看起来像这样:
通常还可以看看关于自定义过滤器的 Spring 文档(如果您还没有)。目前,我们在我当前的公司中使用此配置,如果用户在页面上没有所需的权限,则强制用户重新登录。
How do you check for roles ?
If you define them in your security context like this:
You can set the
defaultFailureUrl
in yourSimpleUrlAuthenticationFailureHandler
and when a user with lesser privileges tries to access a secured URL theFaliureHandler
should redirect you to thedefaultFailureUrl
which could be your login page.You can inject a
FaliureHandler
in the filter at theFORM_LOGIN_FILTER
position.Answering 1) in the comment.
This would be a little more work than I thought given your namespace configuration.
What you need to do is remove the
<form-login>
definition and instead of it add a 'custom'UsernamePasswordAuthenticationFilter
(this is the filter that handles the<form-login>
element).You also need to remove the
<access-denied-handler>
.So your configuration would look something like:
Generally also have a look at the spring docs on custom filters, if you haven't already. We currently use this config in my current company forcing users to relogin if the don't have required privileges on a page.
解决方案 1
注册应用程序范围 ExceptionResolver 使用您喜欢的任何方式。对于前。
将其注册为 bean:(
这就是注册所需的全部内容)。这将适用于您的配置。但是您可能需要从配置中删除
元素。解决方案 2
另一种方法是使用 AccessDeniedHandler。例如:
将其注册为 bean:
并在配置中指定它:
Solution 1
Register an application wide ExeptionResolver using anyway you like. For ex.
register it as a bean:
(that's all you need to register it). This will work for your configuration. Bu you will probably need to remove the
<access-denied-handler>
element from the config.Solution 2
Another way is to use an AccessDeniedHandler. For ex:
register it as a bean:
and specify it in your config: