使用 Spring Security 在表单登录和 OAuth2 登录之间进行选择
Posted
技术标签:
【中文标题】使用 Spring Security 在表单登录和 OAuth2 登录之间进行选择【英文标题】:Choice between form login and OAuth2 login with Spring Security 【发布时间】:2020-08-11 04:03:29 【问题描述】:我想实现一个简单的应用程序,使用户能够使用本地帐户登录或注册新帐户或使用 OAuth2 登录 - 例如Facebook。对于选择 Facebook 的用户,我想自动创建一个本地帐户并使用该帐户登录。
据我了解Spring Social 是dead(如果在项目主页上提到这将非常有帮助,因为它会为像我这样投资学习spring social 的人节省努力)。
我理解的另一件事是“OAuth2 和 OIDC 现在是 Spring Boot 和 Spring Security 生态系统中的一等公民”。似乎正确的方法是使用 Spring Security 5 及其对 OAuth2 的一流支持!
那么……我们走吧。我的application.yaml
:
spring:
security:
oauth2:
client:
registration:
facebook:
client-id: senko
client-secret: topsecret
安全配置:
@Override
protected void configure(HttpSecurity http) throws Exception
// for the ant pattern matcher syntax, please check:
// https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/AntPathMatcher.html
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/authenticate")
.failureUrl("/login?param.error=bad_credentials")
.successForwardUrl("/home")
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID").
and()
.authorizeRequests()
.antMatchers("/login**").permitAll()
.antMatchers("/**").authenticated().
and().
oauth2Login().
loginPage("/login");
@Override
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
auth.userDetailsService(userDetailsService).passwordEncoder(
new BCryptPasswordEncoder());
我的用户服务使用 mysql 支持的本地存储。登录表单简称(thymeleaf):
Login:
<form id="signin" th:action="@/login/authenticate" method="post">
<input id="login" name="username" type="text" size="25"></input>
<input id="password" name="password" type="password" size="25"></input>
<button type="submit">Login In</button>
</form>
Or...:
<a th:href="@/oauth2/authorization/facebook">Sign in with Facebook</a>
到目前为止,我可以使用本地帐户登录。我也可以使用 Facebook 登录。我在这里错过的是成功登录 Facebook 后我应该创建本地用户帐户的部分。实现它的正确方法是什么?我完全一无所知。到目前为止,我尝试的是在谷歌中搜索并阅读OAuth2LoginAuthenticationProvider
的代码。任何帮助将不胜感激。
更新:我正在探索实施 AuthenticationSuccessHandler
是否是一个合适的选择...
【问题讨论】:
当你写你想创建一个本地用户帐户时,你的意思是什么?您想在您的数据库中保留您在身份验证期间从 Facebook 获得的用户详细信息吗? 是的。目前我正在 AuthenticationSuccessHandler 中这样做。 @LachezarBalev 你找到解决方案了吗? 【参考方案1】:您可以注册一个自定义 bean (OAuth2UserService
),它将自动替换默认配置。实际上,下面的示例只是从默认配置委托给一个实现,但允许扩展/添加其他逻辑(在此示例中处理用户)。
@Bean
public OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService()
DefaultOAuth2UserService service = new DefaultOAuth2UserService();
return request ->
OAuth2User user = service.loadUser(request);
System.out.println("User attributes: " + user.getAttributes()); // can be converted and saved
return user;
;
【讨论】:
以上是关于使用 Spring Security 在表单登录和 OAuth2 登录之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring 获取之前捕获 Spring Security 登录表单?
使用 oAuth2.0 和表单登录的 Spring Security
如何在 grails 和现有 oauth2 提供程序中使用 Spring Security 实现基于表单的登录
如何配置 Spring Boot 和 Spring Security 以支持表单登录和 Google OAuth2 登录