我正在使用 Spring Boot 3 和 Spring Security 6。
我的目标是实现使用 JWT 令牌的登录功能。登录页面应该有两个选项:
自定义身份验证流程的工作原理如下:
我想使用Google flow登录应该包括以下步骤:
当我在用户授予访问权限后收到来自 Google 重定向的授权代码时,我将继续执行以下步骤。
分析 Spring Security 的默认功能后,我发现
OAuth2LoginAuthenticationFilter
负责在授权服务器使用代码重定向后进行身份验证。
看来这个过滤器大致执行以下步骤:
因此,我知道我需要创建此过滤器的自定义版本并实施我为我的用例设计的步骤。
但是,我发现 Spring Security 不允许为 OAuth2 登录设置自定义过滤器。它与
OAuth2LoginAuthenticationFilter
紧密结合。请查看此处的 OAuth2LoginConfigurer 类定义。
public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> extends AbstractAuthenticationFilterConfigurer<B, OAuth2LoginConfigurer<B>, OAuth2LoginAuthenticationFilter> {
您对如何正确实现此功能有什么想法吗?
如果我的流程对您来说不合适,我也愿意接受替代解决方案。
在 OAuth2 中,登录(授权代码流)由客户端发起,并重定向到授权服务器。
登录步骤(用户名/密码形式、MFA、使用Google登录等)是授权服务器业务。您在 Spring Security OAuth2 客户端 API 中探索的内容是在用户在授权服务器上进行身份验证后调用的。
因此,您请求的是一个“使用 Google 登录”的授权服务器。您可以使用 Spring 授权服务器项目编写自己的项目,“从货架上”选择一个(例如 Keycloak)或在众多云产品(Auth0、Amazon Cognito、Azure AD 等)中进行选择。几乎都有社交登录功能。
我一直在一个 Spring boot 应用程序中工作,我尝试允许我的用户/客户使用其凭据或使用 google OAuth2 登录,然后向他们返回 JWT 令牌。 所以基本上我所做的就是创建一个从 SimpleUrlAuthenticationSuccessHandler 扩展的类,在其中我在成功的 OAuth2 身份验证后自定义行为,在该类中我获取身份验证的信息(它是 OAuth2User),并且如果它包含的电子邮件存在于其中,我就有效我的数据库,如果属实,我将继续创建令牌的过程。 看代码:
@Configuration
public class CustomOAuth2AuthenticationSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private JwtService jwtService;
@Autowired
private TokenRepository tokenRepository;
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException,
ServletException {
if(authentication instanceof OAuth2AuthenticationToken){
OAuth2User oauth2User = ((OAuth2AuthenticationToken)
authentication).getPrincipal();
Customer customer = customerRepository.
findCustomerByEmail(oauth2User.getAttribute("email").toString()).
orElse(null);
if(customer!=null){
System.out.println("customer exist");
String token = jwtService.generateToken(customer);
//more process you have to do in your logic
response.getWriter().write(token);
response.getWriter().flush();
}else{
//customer doesn't exist, throw an error or create new one
}
}else{
//error
}
}
}
在我的配置类中,我添加了 CustomOAuth2AuthenticationSuccessHandler 类。
.oauth2Login(oauth->{
oauth.successHandler(customOAuth2AuthenticationSuccessHandler);
oauth.failureHandler(new
SimpleUrlAuthenticationFailureHandler("/login?error=true"));
})
这就是我允许用户使用其凭据或使用 OAuth2 google 进行登录的方式。我正在使用 Spring boot 3 和 Spring security 6。也许这可以帮助你:)