如何使用Spring Boot安全的OAuth2登录

2,020 阅读7分钟

学习使用Spring Boot和Spring Security实现基于OAuth2的登录功能。我们将大致了解如何使用第三方授权服务器(例如Github、Twitter和Facebook)应用OAuth2认证。

目录

  1. 1.OAuth2架构
  2. 2.依赖关系
  3. 3.OAuth2客户端配置
  4. 4.默认配置和登录页面
  5. 5.注册ClientRegistrationRepository
  6. 6.定制OAuth2配置
  7. 7.演示
  8. 8.总结

1.OAuth2架构

OAuth 2被称为一个授权框架,其主要目的是允许第三方网站或应用程序访问资源。有时人们把OAuth2称为 SSO认证的委托协议

SSO在一个组织中特别有用,因为用户需要对多个应用程序进行认证。对我们来说,记住多个密码是一种挑战,对组织来说,管理多套凭证也是一种挑战。OAuth2有助于将凭证管理的责任隔离给独立的授权服务器。

通俗地说,单点登录(SSO)安全应用程序是指我们通过授权服务器进行认证,然后应用程序使用刷新令牌让我们保持登录状态。

在本教程中,我们将使用Github作为授权服务器,使用用户提供的凭证来验证用户的身份。

请注意,在我们的案例中,Github也将提供用户的基本信息,所以它也是作为一个资源服务器,允许我们检索用户的详细信息。

2.2.依赖性

为了在Spring boot应用程序中集成基于oauth2的授权,我们需要导入spring-boot-starter-oauth2-client模块。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

在非Boot项目中,我们需要添加spring-security-oauth2-clientspring-security-oauth2-jose依赖项。

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
    <version>5.7.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
    <version>5.7.1</version>
</dependency>

3.OAuth2客户端配置

Spring boot支持许多流行的oauth2认证提供者,只需简单的属性配置。我们只需要在注册完我们的应用程序后,从提供商那里获得客户端ID客户端秘密令牌。

3.1.向提供商注册自定义OAuth2应用程序

我们需要创建一个oauth2登录应用程序到认证提供者的应用程序中,例如,Github谷歌Facebook。请注意,我们可以在一个应用程序中配置多个oauth2提供商。

例如,在Github中,我们创建一个应用程序,如下所示。

应用程序创建后,记下生成的客户端ID和客户端秘密。

3.2.配置客户端标识和客户端秘密

在我们的客户端应用程序方面,Spring boot提供商在检测到oauth2提供商的相应属性时是明智的默认值。这些属性名称有助于区分多个提供者的客户端ID和秘密。

spring.security.oauth2.client.registration.github.client-id=git-id
spring.security.oauth2.client.registration.github.client-secret=git-secret

spring.security.oauth2.client.registration.google.client-id=google-id
spring.security.oauth2.client.registration.google.client-secret=google-secret

spring.security.oauth2.client.registration.facebook.client-id=facebook-id
spring.security.oauth2.client.registration.facebook.client-secret=facebook-secret 

spring.security.oauth2.client.registration.okta.client-id=okta-id
spring.security.oauth2.client.registration.okta.client-secret=okta-secret 

当我们添加至少一个oauth2客户端时,spring boot将启用Oauth2ClientAutoConfiguration 类并设置所有必要的bean。

在实际应用中,客户端id和secret应该从安全的配置源或数据库中获得,我们不应该在源代码中直接写入凭证。

4.默认配置和登录页面

默认情况下,如果我们不提供任何自定义的登录页面或逻辑,只需添加上述属性就可以为spring安全模块生成的默认登录页面提供服务,它将呈现属性文件中配置的登录选项。

默认安全相当于只配置了http.oauth2Login() 方法。*oauth2Login()*方法将OAuth2LoginAuthenticationFilter 添加到过滤器链中,拦截请求并应用OAuth 2认证逻辑。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
         .anyRequest().authenticated()
         .and()
         .oauth2Login();
    }
}

Spring Security使用**ClientRegistration** 接口来表示应用程序中的Oauth2提供者注册细节。为了使提供者能够正常工作,spring-security必须有以下信息。

  • 客户端ID和秘密
  • 用于认证的授予类型
  • 重定向URI
  • 作用域

Spring安全自动配置在枚举 CommonOAuth2Provider ,为以下内置的提供者提供了大部分这些细节。

  • 谷歌
  • GitHub
  • Facebook
  • 奥克塔

注册一个非内置的提供者,我们需要自己定义所有的配置元素

5.注册ClientRegistrationRepository

ClientRegistrationRepositoryOAuth2LoginAuthenticationFilter用来获取配置的ClientRegistration类型。如果我们不使用属性配置,那么我们需要在Java配置中定义它。

ClientRegistrationRepository与*UserDetailsService接口非常相似,有助于在典型的基于用户名-密码的登录表单中通过用户名找到UserDetails 。它通过其注册ID找到ClientRegistration*。

Spring Security提供InMemoryClientRegistrationRepository,在内存中存储ClientRegistration 的实例。

@Bean
  public ClientRegistrationRepository clientRepository() {

    ClientRegistration githubRegistration =
        CommonOAuth2Provider.GITHUB.getBuilder("github")
        .clientId("id")
        .clientSecret("secret")
        .build();

    ClientRegistration facebookRegistration =
        CommonOAuth2Provider.FACEBOOK.getBuilder("facebook")
        .clientId("id")
        .clientSecret("secret")
        .build();

    return new InMemoryClientRegistrationRepository(githubRegistration,
        facebookRegistration);
  }

6.自定义OAuth2配置

尽管Spring boot为所有的OAuth2配置元素提供了合理的默认值,但我们可以根据具体的要求定制特定的部分。

6.1.自定义登录页面

spring security生成的默认登录页面对于POC和入门来说已经足够好了。但对于一个生产级的应用程序,我们需要有一个与应用程序其他部分主题相匹配的自定义登录页面。

为了创建一个自定义的登录页面,我们需要提供http元素的*loginPage()*方法,如下所示。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
	      .antMatchers("/login").permitAll()
	      .anyRequest().authenticated()
      .and()
	      .oauth2Login()
	      .loginPage("/login");
}

现在我们需要为URL*/login*创建一个处理方法,为登录页面呈现自定义的HTML。

@Controller
public class LoginController {

  @GetMapping("/login")
  public String login() {
    return "oauth2-login.html";
  }
}

登录页面的HTML可以根据需求来创建。

<!doctype html>
<html lang="en">

<body>
<div class="container">
    <h3>OAuth2 Login Demo</h3>
    <p>Login to HowToDoInJava:</p>
    <div>
        <div>
            With GitHub: <a href="/oauth2/authorization/github">click here</a>
        </div>
        <div>
            With Google: <a href="/oauth2/authorization/google">click here</a>
        </div>
        <div>
            With Facebook: <a href="/oauth2/authorization/facebook">click here</a>
        </div>
    </div>
</div>
</body>

</html>

6.2.处理登录成功和失败

为了控制认证后显示哪一个页面,我们有两个选择。

  • 提供登录和失败的URLs作为*defaultSuccessUrl()failationUrl()*方法
  • successHandler()failureHandler()方法中提供自定义逻辑,或者定义AuthenticationSuccessHandlerAuthenticationFailureHandler 类型的豆子。

提供登录成功和失败的URL很简单。

.oauth2Login()
  .defaultSuccessUrl("/home")
  .failureUrl("/login");

处理程序更适合于执行自定义逻辑,如审核认证信息,然后将请求转发到相应的URL。

@Bean
  AuthenticationSuccessHandler authenticationSuccessHandler() {
    return new CustomAuthenticationSuccessHandler();
  }

  @Bean
  AuthenticationFailureHandler authenticationFailureHandler() {
    return new CustomAuthenticationFailureHandler();
  }

7.演示

为了快速演示,在*http://localhost:8080/login*URL上加载登录页面。它将显示所有配置的OAuth2提供者。

现在点击Github的链接,它将重定向到Github门户的登录页面。

一旦我们输入正确的凭证,我们将被重定向到授权访问页面。

最后,我们允许访问,浏览器将被重定向到我们应用程序的安全主页。因为现在用户已经被认证和授权,他可以在没有任何访问拒绝的错误下访问主页。

8.结语

在这个Spring安全教程中,我们学习了如何在Spring boot应用程序中配置基于OAuth2授权的登录安全。我们学习了默认应用的Oauth安全,以及自定义OAuth配置的各种元素。

我们还学会了创建一个自定义的登录页面,并使用自定义处理程序处理成功和失败的情况。

学习愉快!!

源代码在Github上

这个帖子有帮助吗?

如果你喜欢这个帖子,请告诉我们。这是我们能够改进的唯一方法。

没有

推荐阅读。

  1. Spring Security数据库支持的表单登录
  2. 禁用Spring Boot中的Spring Security
  3. Spring Security表单登录示例
  4. Spring Boot - OAuth2授权和资源服务器
  5. 使用Spring Boot REST APIs添加基于角色的安全性
  6. Spring Security中的UserDetailsService指南
  7. Spring Security中的密码编码器
  8. Spring Security中的自定义认证提供者
  9. Spring Security的上下文传播到线程
  10. 启用Spring Security的调试日志