Spring Security在运行时注销用户
我正在实现一个基于Spring的Web应用程序,该应用程序将Spring
Security与DaoAuthenticationProvider一起使用。为此,我创建了一个具有布尔isEnabled()的User类。方法,因为它实现了Springs
UserDetails接口。因此,如果“未启用”用户,则该用户将无法登录。到目前为止,一切都很好。如果我在运行时仍处于登录状态时禁用了一个用户,(似乎)该用户一直保持登录状态,直到http会话结束,但我希望该用户在将其设置为禁用后立即注销。我怎样才能做到这一点?
谢谢。
回答:
假设您有一个能够禁用用户的正在运行的Web应用程序,我将向您展示如何在运行时锁定那些用户。
基本思想是使用刷新的用户详细信息重新验证每个请求。为此,您将需要一个自定义项SecurityContextRepository
,该自定义项将丢弃保存在http会话中的用户详细信息。
public class RefreshingUserDetailsSecurityContextRepository implements SecurityContextRepository { private final SecurityContextRepository delegate;
private final UserDetailsService userDetailsService;
public RefreshingUserDetailsSecurityContextRepository(final SecurityContextRepository delegate, final UserDetailsService userDetailsService) {
Assert.notNull(delegate);
Assert.notNull(userDetailsService);
this.delegate = delegate;
this.userDetailsService = userDetailsService;
}
@Override
public SecurityContext loadContext(final HttpRequestResponseHolder requestResponseHolder) {
SecurityContext securityContext = delegate.loadContext(requestResponseHolder);
if(securityContext.getAuthentication() == null) {
return securityContext;
}
Authentication principal = securityContext.getAuthentication();
UserDetails userDetails = userDetailsService.loadUserByUsername(principal.getName());
//this code has to be modified when using remember me service, jaas or a custom authentication token
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword());
securityContext.setAuthentication(token);
saveContext(securityContext, requestResponseHolder.getRequest(), requestResponseHolder.getResponse());
return securityContext;
}
@Override
public void saveContext(final SecurityContext context, final HttpServletRequest request, final HttpServletResponse response) {
delegate.saveContext(context, request, response);
}
@Override
public boolean containsContext(final HttpServletRequest request) {
return delegate.containsContext(request);
}
}
RefreshingUserDetailsSecurityContextRepository
只包装默认值SecurityContextRepository
,即HttpSessionSecurityContextRepository
。因此,您无需担心会话超时或SecurityContext
自己存储。在该loadContext
方法中,用户详细信息将刷新并发userDetailsService
回给SecurityContext
发给呼叫者之前。
不要将用户权限传递给UsernamePasswordAuthenticationToken
构造函数。否则,令牌将标记为已认证,并且永远不会触发重新认证!
当心RefreshingUserDetailsSecurityContextRepository
限制了你UsernamePasswordAuthenticationToken
。例如,如果您想使用Jaas,Spring
Security,请记住我或不是源自UsernamePasswordAuthenticationToken
您的自定义身份验证令牌,它需要适应
RefreshingUserDetailsSecurityContextRepository
您的需求。
添加RefreshingUserDetailsSecurityContextRepository
到您的安全配置。
<security:http use-expressions="true" security-context-repository-ref="refreshingUserDetailsSecurityContextRepository"> <security:intercept-url ... />
<security:form-login ... />
<security:logout />
</security:http>
<bean id="refreshingUserDetailsSecurityContextRepository" class="security.RefreshingUserDetailsSecurityContextRepository">
<constructor-arg index="0">
<bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
</constructor-arg>
<constructor-arg index="1" ref="userDetailsService" />
</bean>
而已。已登录但已禁用的用户会在下一页请求中被重定向回登录页面。
这是一个功能齐全的示例。
以上是 Spring Security在运行时注销用户 的全部内容, 来源链接: utcz.com/qa/413304.html