gpt4 book ai didi

java - Spring Security 在运行时注销用户

转载 作者:行者123 更新时间:2023-12-01 18:25:21 25 4
gpt4 key购买 nike

我正在实现一个基于 Spring 的 Web 应用程序,该应用程序使用 Spring Security 和 DaoAuthenticationProvider。因此,我创建了一个 User 类,它具有 boolean isEnabled(); 方法,因为它实现了 Springs UserDetails 接口(interface)。因此,如果用户“未启用”,则该用户将无法再登录。到目前为止一切顺利。

如果我在运行时禁用仍然登录的用户,(似乎)该用户将保持登录状态直到http session 结束,但我希望用户在我将其禁用后立即注销。我怎样才能做到这一点?

最佳答案

假设您有一个正在运行的 Web 应用程序能够禁用用户,我将向您展示如何在运行时锁定这些用户。

基本思想是使用刷新的用户详细信息重新验证每个请求。为此,您需要一个自定义 SecurityContextRepository哪个丢弃保存在 http session 中的用户详细信息。

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);
}
}

RefreshingUserDetailsS​​ecurityContextRepository 只是包装默认的 SecurityContextRepository,即 HttpSessionSecurityContextRepository 。因此,您无需担心 session 超时或存储 SecurityContext靠你自己。在 loadContext 方法中,用户详细信息通过 userDetailsS​​ervice 进行刷新,并在将其分发给调用者之前写回 SecurityContext

不要传递用户authoritiesUsernamePasswordAuthenticationToken构造函数。否则, token 将被标记为已通过身份验证,并且永远不会触发重新身份验证!

请注意,RefreshingUserDetailsS​​ecurityContextRepository 限制您使用UsernamePasswordAuthenticationToken。例如,如果您想使用 Jaas、Spring Security 记住我或不是从 UsernamePasswordAuthenticationToken 派生的自定义身份验证 token ,您需要根据您的需求调整 RefreshingUserDetailsS​​ecurityContextRepository

RefreshingUserDetailsS​​ecurityContextRepository 添加到您的安全配置中。

<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>

就是这样。您已登录但已禁用的用户会在下一页请求时重定向回登录页面。

这是一个功能齐全的 example .

关于java - Spring Security 在运行时注销用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26393518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com