您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Spring Security在运行时注销用户

Spring Security在运行时注销用户

假设您有一个能够禁用用户的正在运行的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>

而已。已登录但已禁用的用户会在下一页请求中被重定向登录页面

这是一个功能齐全的示例

Java 2022/1/1 18:15:34 有415人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶