gpt4 book ai didi

java - Spring Security 的特殊登录

转载 作者:太空狗 更新时间:2023-10-29 22:40:31 25 4
gpt4 key购买 nike

我目前工作的公司有一种特殊的身份验证流程。

确实,多个用户可以拥有相同的登录名和密码。因此,要再次识别它们,用户必须提供他的电子邮件。但同样,在少数情况下,可能会涉及多个用户,然后用户必须提供其公司 ID 才能进行完全身份验证。

所以,我的问题是,在某些情况下,身份验证过程不能一步完成,这是 Spring Security 开箱即用处理的大多数应用程序的默认行为。

所以我的问题是:用 Spring Security 实现这个特殊登录过程的最简单方法是什么?

提前致谢。

最佳答案

我必须执行类似的两步身份验证过程。这听起来很简单,但找到正确的注入(inject)位置和正确的覆盖方法并不容易。基本思想是为中间身份验证(电子邮件检查)提供另一个角色,然后在确认电子邮件后授予完全访问权限。

希望下面的代码提供了一些很好的提示,说明如何针对您的场景解决它。

创建自定义 UserDetailsChecker 来处理身份验证后检查。这是确定用户角色的地方。

public class CustomPostAuthenticationChecks implements UserDetailsChecker {

public void check(UserDetails userDetails) {

CustomUser customUser = (CustomUser) userDetails;
if (customUser.needsEmailAuthentication()) {
// Get rid of any authorities the user currently has
userDetails.getAuthorities().clear();
// Set the new authority, only allowing access to the
// email authentication page.
userDetails.getAuthorities().add(new GrantedAuthorityImpl("ROLE_NEEDS_EMAIL_AUTH"));
} else {
userDetails.getAuthorities().add(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"));
}
}

创建自定义 AuthenticationSuccessHandler。此类根据用户的角色将用户发送到正确的 URL。

public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {

String targetUrl = null;

SecurityContext securityContext = SecurityContextHolder.getContext();

Collection<GrantedAuthority> authorities = securityContext.getAuthentication().getAuthorities();

if (authorities.contains(new GrantedAuthorityImpl("ROLE_NEEDS_EMAIL_AUTH"))) {
targetUrl = "/authenticate";
} else if (authorities.contains(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"))) {
targetUrl = "/authorized_user_url";
} else {
targetUrl = super.determineTargetUrl(request, response);
}

return targetUrl;
}

用户的电子邮件地址通过身份验证后,您需要授予用户对应用程序的完全访问权限:

public void grantUserAccess(User user) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication auth = securityContext.getAuthentication();
user.getAuthorities().clear();
user.getAuthorities().add(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"));
Authentication newAuth = new UsernamePasswordAuthenticationToken(user, auth.getCredentials(), user.getAuthorities());
securityContext.setAuthentication(newAuth);
}

定义自定义身份验证提供程序以注册您的 CustomPostAuthenticationChecks:

<security:authentication-manager>
<security:authentication-provider ref="customAuthenticationProvider" />
</security:authentication-manager>

<bean id="customAuthenticationProvider" class="YourAuthenticationProvider">
<property name="postAuthenticationChecks">
<bean class="CustomPostAuthenticationChecks"/>
</property>
</bean>

如果您使用标准的表单登录标记,您可以轻松定义自定义 AuthenticationSuccessHandler:

<security:form-login authentication-success-handler-ref="customAuthenticationSuccessHandler">

...

<bean id="customAuthenticationSuccessHandler" class="CustomAuthenticationSuccessHandler"/>

/authenticate URL 添加新的角色拦截规则,因此只有需要更多身份验证的用户才能访问该页面。

<security:intercept-url pattern="/authenticate/**" access="hasRole('ROLE_NEEDS_EMAIL_AUTH')" />
<security:intercept-url pattern="/authorized_user_url/**" access="hasRole('ROLE_AUTHORIZED_USER')" />

关于java - Spring Security 的特殊登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6781535/

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