lrkgithub / Spring-Security-Reference-CN

8 stars 4 forks source link

6. Java 配置 #4

Open lrkgithub opened 5 years ago

lrkgithub commented 5 years ago

章节Ⅱ Servlet 应用

6. Java 配置

对 Java Configuration 的基础支持在 Sprng 3.1 版本中就被加入到了 Spring Framework 中。从 Spring Security 3.2 开始, Spring Security 就支持 Java Configuration 使用户可以脱离任何 XML 来简单地配置 Spring Security。

如果你对 7 节,安全命名空间配置 熟悉的话,你应该能找到不少它和 Security Java Configuration 支持之间的共通性。

Spring Security 提供了不少示例来说明如何使用 Spring Security Java Configuration

6.1 Hello Web Security Java Configuration

第一步是创建我们的 Spring Security Java Configuration 。这个配置创建了一个 Servlet Filter ,就是众所周知的 springSecurityFilterChain ,它会对应用中的所有安全(保护应用 URLs,验证提交的用户名和密码,重定向 到登录表单)负责。在下面,你可以找到最基本的 Spring Security Java Configuration :

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;

@EnableWebSecurity
public class WebSecurityConfig implements WebMvcConfigurer {

    @Bean
    public UserDetailsService userDetailsService() throws Exception {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());
        return manager;
    }
}

这确实不是很多配置,但它的作用却很大。你可以在下面找到一个功能摘要:

6.1.1 AbstractSecurityWebApplicationInitializer

下一步是使用 war 来注册 springSecurityFilterChain 。这在 Servlet 3.0+ 环境中,可以基于 Spring's WebApplicationInitializer support 用 Java Configuration 来完成。

6.1.2 AbstractSecurityWebApplicationIInitializer 不依赖 Spring 容器

如果你没有使用 Spring or Spring MVC ,你就需要传入 wenSecurityConfig 到超类中,确保配置被获取。如下所示:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(WebSecurityConfig.class);
    }
}

SecurityWebApplicationInitializer 会做以下的事情:

6.1.3 AbstractSecurityWebApplicationInitializer 依赖 Spring 容器

如果我们在应用的其他地方使用了 Spring ,那么大概已经有了一个用来加载 Spring Configuration 的 WebApplicationInitializer 。如果我们使用之前的配置,会得到一个 error。反之,我们应该将 Spring Security 注册到已有的 ApplicationContext 中。举例来说,如果我们使用 Spring MVC 或我们的 SecurityWebApplicationInitializer ,看上去会是这样:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

}

这会简单地为你的应用的每一个 URL 注册一个 springSecurityFilterChain Filter 。之后,我们需要确保 webSecurityConfig 被已经存在的 ApplicationInitializer 加载。举例来说,如果我们使用 Spring MVC ,这应该被加入到 getRootConfigClass()

public class MvcWebApplicationInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { WebSecurityConfig.class };
    }

    // ... other overrides ...
}

6.2 HttpSecurity

至此,我们的 WebSecurityConfig 只包含关于认证用户的相关信息。Spring Seucrity 怎么知道我们希望所有用户都被认证呢? Spring Security 怎么知道我们希望支持基于表单的认证?这是因为 WebSecurityConfiguraerAdapter 提供了一个默认配置,在 cofigure(HttpSecurity http) 方法中:

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .and()
        .httpBasic();
}

默认配置有如下内容:

你会注意到这和 XML 命名空间的配置很相似:

<http>
    <intercept-url pattern="/**" access="authenticated"/>
    <form-login />
    <http-basic />
</http>

Java Configuration 使用 and() 来表示和 XML 关闭标志(<.../>)一样的作用,允许用户继续配置父类。如果你阅读代码的话,它也表达同样的意思。我希望配置认证请求,配置基于表单登录,配置 HTTP Basic 认证。

6.3 Java Configuration 和 表单登录

你可能想知道表单登录来自哪里,因为目前为止我们没有在任何的 HTML 文件或者 JSPs 里提到。因为 Spring Security 的默认配置没有明确地设置一个 URL 用作登录页面, Spring Security 自动生成了这一页面,基于使能的特性并且使用标准的 URL 值来处理提交的登录,用户会在登陆之后发送给默认的 URL,以及后续操作。

虽然自动生成的登录页面在启动时十分方便,运行起来也很快,但是绝大多数应用希望提供自己的登录页面。为了达到这个目的,我们可以更新我们的配置,如下所示:

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

下面是一个用 JSP 实现的当前的配置的示例:

下面是一个我们当前配置的登录页面。如果这些默认配置不符合我们的需求,可以简单地更新这些配置

<c:url value="/login" var="loginUrl"/>
<form action="${loginUrl}" method="post">       
    <c:if test="${param.error != null}">        
        <p>
            Invalid username and password.
        </p>
    </c:if>
    <c:if test="${param.logout != null}">       
        <p>
            You have been logged out.
        </p>
    </c:if>
    <p>
        <label for="username">Username</label>
        <input type="text" id="username" name="username"/>  
    </p>
    <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/>  
    </p>
    <input type="hidden"                        
        name="${_csrf.parameterName}"
        value="${_csrf.token}"/>
    <button type="submit" class="btn">Log in</button>
</form>

6.4 授权请求

我们的示例仅仅针对我们应用的每一个 URL ,都要求用户进行认证。我们可以通过在 http.authorizeRequests() 方法下增加多个子配置,来指定自定义需求。举例来说:

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()                                                                
            .antMatchers("/resources/**", "/signup", "/about").permitAll()                  
            .antMatchers("/admin/**").hasRole("ADMIN")                                      
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            
            .anyRequest().authenticated()                                                   
            .and()
        // ...
        .formLogin();
}

6.5 处理登出

lrkgithub commented 5 years ago

6.5 处理登出

当使用 WebSecurityConfigurerAdapter 时,登出功能是自动增加的。默认下,请求 URL /logout 将用户登出,步骤如下:

然后,和配置登录功能类似,你也有许多选择来更细化配置登出需求

protected void configure(HttpSecurity http) throws Exception {
    http
        .logout()                                                                
            .logoutUrl("/my/logout")                                                 
            .logoutSuccessUrl("/my/index")                                           
            .logoutSuccessHandler(logoutSuccessHandler)                              
            .invalidateHttpSession(true)                                             
            .addLogoutHandler(logoutHandler)                                         
            .deleteCookies(cookieNamesToClear)                                       
            .and()
        ...
}

登出配置当然也可以使用 XML 命名空间方式来做。请查询 Spring Security XML Namespace 章节关于 logout element 的内容来获取更详细的内容。

通常,为了配置登出功能,你可以添加 LogoutHandler 和/或 LogoutSuccessHandler 实现。在更多场景下,这些 handlers 会在背后使用 fluent API 来完成。

6.5.1 LogoutHandler

通常,LogoutHandler 实现说明它是能够参与登出实现的类。他们被用来进行必要的清理工作。因此,他们不应该抛出异常。框架提供了多个实现:

请阅读 [10.5.4节, Remember-Me 接口和实现](),来获取更多细节。

6.5.2 LogoutSuccessHandler

LogoutSuccessHandlerLogoutFilter 成功处理登出之后被调用,用来处理,例如,重定向或者转发到合适远端地址。请注意,这个接口和 LogoutHandler 非常类似,但是会抛出异常。

下面的实现是框架提供的:

正如之前提到的,你并不需要直接指定 SimpleUrlLogoutSuccessHandler 。反之,fluent API 提供了一个快捷方式来操作,通过设置 logoutSuccessUrl() 。在内部,这将设置一个 SimpleUrlLogoutSuccessHandler 。登出成功后请求被重定向到提供的 URL 地址。默认地址是 /login?logout

在 REST API 场景下,HttpStatusReturningLogoutSuccessHandler 是很有意思的。在登出成功之后不是重定向到指定地址,而是用 LogoutSuccessHandler 提供的一个普通 HTTP 状态码返回。如果没有特别指定,默认是 200。

6.5.3 更多与登出相关的参考

6.6 OAuth 2.0 客户端

lrkgithub commented 5 years ago

6.6 OAuth 2.0 客户端

OAuth 2.0 客户端特性支持 OAuth 2.0 Authorization 框架定义的客户角色。

以下是可用的重要特性:

HttpSecurity.oauth2Client() 提供了许多配置选项来配置 OAuth 2.0 客户端。下面的代码展示了,对oauth2Client() DSL 全部可用的配置选项:

@EnableWebSecurity
public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .oauth2Client()
                .clientRegistrationRepository(this.clientRegistrationRepository())
                .authorizedClientRepository(this.authorizedClientRepository())
                .authorizedClientService(this.authorizedClientService())
                .authorizationCodeGrant()
                    .authorizationRequestRepository(this.authorizationRequestRepository())
                    .authorizationRequestResolver(this.authorizationRequestResolver())
                    .accessTokenResponseClient(this.accessTokenResponseClient());
    }
}

接下来的章节,会仔细研究这些可选配置的细节:

6.6.1 ClientRegistration

ClientRegistration 代表了注册到 OAuth 2.0 或者 OpenID Connect 1.0 Provider 的客户端。

一个客户端注册类持有许多信息,例如,客户 ID ,客户端密钥,授权认证类型,重定向 URL, 范围,授权 URI ,等等其他细节。

以下是 ClientRegistration 和它的属性:

public final class ClientRegistration {
    private String registrationId;  
    private String clientId;    
    private String clientSecret;    
    private ClientAuthenticationMethod clientAuthenticationMethod;  
    private AuthorizationGrantType authorizationGrantType;  
    private String redirectUriTemplate; 
    private Set<String> scopes; 
    private ProviderDetails providerDetails;
    private String clientName;  

    public class ProviderDetails {
        private String authorizationUri;    
        private String tokenUri;    
        private UserInfoEndpoint userInfoEndpoint;
        private String jwkSetUri;   
        private Map<String, Object> configurationMetadata;  

        public class UserInfoEndpoint {
            private String uri; 
            private AuthenticationMethod authenticationMethod;  
            private String userNameAttributeName;   

        }
    }
}
6.6.2 ClientRegistrationRepository

ClientRegistrationRepository 作为 OAuth 2.0 / OpenID Connect 1.0 ClientRegistration 的源。

客户端注册信息最终在相关的认证服务器上存储和维护。这个源提供了获取主要客户端注册信息子集的能力,这个子集也是存储的认证服务器上。

Spring Boot 2.x 自定配置将 spring.security,oauth2.registration.[registrationId] 下的所有属性绑定到 ClientRegistration ,并把每一个 ClientRegistration 存储在 ClientRegistrationRepository 中。

默认的 ClientRegistrationRepositoryInMemoryRegistrationRepository

自动注入同样注册 ClientRegistrationRepository 为一个 ApplicationContext@Bean ,因此如果别的应用需要这个 bean ,就可以依赖注入。

下面是一个示例:

@Controller
public class OAuth2ClientController {

    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;

    @RequestMapping("/")
    public String index() {
        ClientRegistration googleRegistration =
            this.clientRegistrationRepository.findByRegistrationId("google");

        ...

        return "index";
    }
}
6.6.3 OAuth2AuthorizedClient

OAuth2AuthorizedClient 是一个已授权的客户端的。当终端使用者(资源所有者)已授权客户访问受保护的资源时,就认为客户是已获得授权的。

OAuth2AuthorizedClient 用来将 OAuth2AccssToken (或者可选的 OAuthRefreshTokne)和 ClientRegistration (客户)以及 资源所有者相关联,后者是终端使用者的授权 Principal

6.6.4 OAuth2AuthorizedClientRepository / OAuth2AuthorizedClientService
lrkgithub commented 5 years ago
6.6.4 OAuth2AuthorizedClientRepository / OAuth2AuthorizedClientService

OAuth2AuthorizedClientRepository 的任务是在 Web 请求之间,持久化 OAuth2AuthorizedClient(s) 。然而, OAuth2AuthorizedClientService 的主要作用是在应用级别管理 OAuth2AuthorizedClient

从开发者角度, OAuth@AuthorizedClientRepositoryOAuthorizedClientService 提供了寻找与客户端关联的 OAuth2AccessToken 的功能,以便能够是用来它初始化对受保护资源的请求。

Spring Boot 2.x 在自动配置中注册了一个 OAuthorizedClientRepository 和/或 OAuthorizedClientService @BeanApplicationContext

开发者可能也会注册一个 OAuthorizedClientRepositoryOAuthAuthorizedClientService @BeanApplicationContext 中(重写 Spring Boot 的自动配置),这样就能够寻找与特定的 ClientRegistration (客户端)相关联的 OAuth2AccessToken

下面是一个示例:

@Controller
public class OAuth2LoginController {

    @Autowired
    private OAuth2AuthorizedClientService authorizedClientService;

    @RequestMapping("/userinfo")
    public String userinfo(OAuth2AuthenticationToken authentication) {
        // authentication.getAuthorizedClientRegistrationId() returns the
        // registrationId of the Client that was authorized during the oauth2Login() flow
        OAuth2AuthorizedClient authorizedClient =
            this.authorizedClientService.loadAuthorizedClient(
                authentication.getAuthorizedClientRegistrationId(),
                authentication.getName());

        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

        ...

        return "userinfo";
    }
}
6.6.5 RegisteredOAuth2AuthorizedClient

@RegisteredOAuth2AuthorizedClient 注解能够为 OAuth2AuthorizedClient 类型的方法参数注入值。跟通过 OAuth2AuthorizedClientService 寻找 OAuth2AuthorizedClient 相比,这是一个简单的方法。

@Controller
public class OAuth2LoginController {

    @RequestMapping("/userinfo")
    public String userinfo(@RegisteredOAuth2AuthorizedClient("google") OAuth2AuthorizedClient authorizedClient) {
        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

        ...

        return "userinfo";
    }
}

OAuth2AuthorizedClientArgumentResolver 管理 @RegisteredOAuth2AuthorizedClient ,并且提供一下能力:

6.6.6 AuthorizationRequestRepository

AuthorizationRequestRepository 负责从 Authorization Request 到达到 Authorization Response 被接收到,获取 OAuth2AuthorizedRequest 的持久化内容(回调)。

OAuth2AuthorizationRequest 被用来关联和验证授权响应。

AuthorizationRequestRepository 的默认实现是 HttpSessionOAuth2AuthorizationRequestRepository 。这个实现,是把 OAuth2AuthorizationRequest 存储在 HttpSession

如果你想自己实现一个 AuthorizationRequestRepository 来把 OAuth2AuthorizationRequest 存储在 Cookie 。你可以像下面的代码一样配置:

@EnableWebSecurity
public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .oauth2Client()
                .authorizationCodeGrant()
                    .authorizationRequestRepository(this.cookieAuthorizationRequestRepository())
                    ...
    }

    private AuthorizationRequestRepository<OAuth2AuthorizationRequest> cookieAuthorizationRequestRepository() {
        return new HttpCookieOAuth2AuthorizationRequestRepository();
    }
}
6.6.7 OAuth2AuthorizationRequestResolver

OAuth2AuthorizationRequestResolver 的主要作用从受保护的 web 请求中解析 OAuth2AuthorizationRequest 。默认实现 DefaultOAuth2AuthorizationRequestResolver 会匹配(默认)路径 /oauth2/authorization/{registrationId} ,并从中提取出 registrationId ,并用它位相关联的 ClientRegistration 构建一个 OAuth2AuthorizationRequest

OAuth2AuthorizationRequestResolver 的一个主要使用场景是,利用它来解析 OAuth 2.0 Authorization Framework 中定义的标准参数之外的参数。

举例来说, OpenID Connect 通过扩展 OAuth 2.0 Authorization Framework 定义的标准参数,来为 Authorization Code Flow 定义了一下额外的 OAuth 2.0 请求参数。其中一个扩展的参数是 orimpt

可选的。空格分隔。用大小写敏感的 ASCII 字符串值来区分认证服务器是否提示终端使用者需要重认证或者认证成功。定义的值有: none,login,consent,select_account。

下面的例子展示了如何实现一个 OAuth2AuthorizationRequestResolver ,并为 oauth2Login()方法的认证请求自定义了一个 prompt=consect 的请求参数。

@EnableWebSecurity
public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .authorizationEndpoint()
                    .authorizationRequestResolver(
                            new CustomAuthorizationRequestResolver(
                                    this.clientRegistrationRepository));    
    }
}

public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
    private final OAuth2AuthorizationRequestResolver defaultAuthorizationRequestResolver;

    public CustomAuthorizationRequestResolver(
            ClientRegistrationRepository clientRegistrationRepository) {

        this.defaultAuthorizationRequestResolver =
                new DefaultOAuth2AuthorizationRequestResolver(
                        clientRegistrationRepository, "/oauth2/authorization");
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
        OAuth2AuthorizationRequest authorizationRequest =
                this.defaultAuthorizationRequestResolver.resolve(request);  

        return authorizationRequest != null ?   
                customAuthorizationRequest(authorizationRequest) :
                null;
    }

    @Override
    public OAuth2AuthorizationRequest resolve(
            HttpServletRequest request, String clientRegistrationId) {

        OAuth2AuthorizationRequest authorizationRequest =
                this.defaultAuthorizationRequestResolver.resolve(
                    request, clientRegistrationId);    

        return authorizationRequest != null ?   
                customAuthorizationRequest(authorizationRequest) :
                null;
    }

    private OAuth2AuthorizationRequest customAuthorizationRequest(
            OAuth2AuthorizationRequest authorizationRequest) {

        Map<String, Object> additionalParameters =
                new LinkedHashMap<>(authorizationRequest.getAdditionalParameters());
        additionalParameters.put("prompt", "consent");  

        return OAuth2AuthorizationRequest.from(authorizationRequest)    
                .additionalParameters(additionalParameters) 
                .build();
    }
}

OAuth2AuthorizationRequest.Builder.build() 构造了一个 OAuth2AuthorizationRequest.authorizationRequestUri ,它代表完整的 Authorization Request URI,包含了使用 application/x-www-form-urlencoded 的 query 参数。

前面的示例,展示了增加一个自定义参数到标准参数上的常用场景。然而,如果你希望去除或者修改标准参数,或者你的需求要比这更高级,那么你需要得到构造一个 Authorization Request URI 的全部控制权。那么,此时你就需要重写 OAuth2AuthorizationRequest.authorizationRequestUri 参数。

下面的例子,展示了一种与前面不同的 customAuthorizationRequest() 方法,覆盖了 OAuth2AuthorizationRequest.authorizationRequestUri 属性。

private OAuth2AuthorizationRequest customAuthorizationRequest(
        OAuth2AuthorizationRequest authorizationRequest) {

    String customAuthorizationRequestUri = UriComponentsBuilder
            .fromUriString(authorizationRequest.getAuthorizationRequestUri())
            .queryParam("prompt", "consent")
            .build(true)
            .toUriString();

    return OAuth2AuthorizationRequest.from(authorizationRequest)
            .authorizationRequestUri(customAuthorizationRequestUri)
            .build();
}
6.6.8 OAuth2AccessTokenResponseClient

OAuth2AccessTokenResponseClient 的主要作用是在 认证服务器的 Token Endponit 用认证授权凭证交换访问令牌凭证。

OAuth2AccessTokenResponseClientauthorization_code 的默认实现是 DefaultAuthorizationCodeTokenResponseClient ,它使用了 RestOperations 在 Token Endpoint 来交换认证码和访问令牌。

DefaultAuthorizationCodeTokenResponseClient 是十分灵活的,允许你自定义 Token Request 的预处理和/或 Token Response 的后处理。

如果你需要自定义 Token Request 的预处理,你可以使用 DefaultAuthorizationCodeTokenResponseClient.setRequestEntityConverter() 方法,入参为自定义的 Converter<OAuth2AuthorizationCodeGrantRequest, RequestEntity<?>> 。默认实现 OAuth2AuthorizationCodeGrantRequestEntityConverter 构建了一个 RequestEntity 代表了标准的 OAuth 2.0 Access Token Request 。当然,提供一个自定义的 Converter 会允许你扩展标准的 Token Request,例如添加一个自定义的参数。

自定义的 Converter 必须返回一个合法的 RequestEntity ,这样才能够被预期的 OAuth 2.0 Provider 理解。

另一方面,如果你需要自定义 Token Response 的后处理,你需要使用 DefaultAuthorizationCodeTokenResponseClient.setRestOperations() ,入参为一个自定义配置的 RestOperations 。默认的 RestOperations 如下配置:

RestTemplate restTemplate = new RestTemplate(Arrays.asList(
        new FormHttpMessageConverter(),
        new OAuth2AccessTokenResponseHttpMessageConverter()));

restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());

在发送 OAuth 2.0 Access Token Request 时候, Spring MVC 的 FormHtpMessageConverter 会被用到。

OAuth2AccessTokenResponseHttpMessageConverter 是一个处理 OAuth 2.0 Access Token Response 的 HttpMessageConverter。你可以使用 OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter() ,入参是一个自定义的 Converter<Map<String, String>, OAuth2AccessTokenResponse>,用来转换 OAuth 2.0 Token Response 参数到一个 OAuth2AccessTokenResponse

OAuth2ErrorResponseErrorHandler 是一个 ResponseErrorHandler ,专门来处理 OAuth 2.0 Error(400 Bad Request) 。它用 OAuth2ErrorHttpMessageConverter 来转换 OAuth 2.0 Error 参数到一个 OAuth2Error

无论你是自定义一个 DefaultAuthorizationCodeTokenResponseClient 还是提供你自己实现的 OAuth2AccessTokenResponseClient ,你都需要和如下代码一样的配置:

@EnableWebSecurity
public class OAuth2ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .oauth2Client()
                .authorizationCodeGrant()
                    .accessTokenResponseClient(this.customAccessTokenResponseClient())
                    ...
    }

    private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> customAccessTokenResponseClient() {
        ...
    }
}

6.7 OAuth 2.0 Login

利用 OAuth 2.0 Login 特性,应用可以使用户通过已有的程序来登录,例如 OAuth 2.0 Provider(例如,Github),或者 OpenID Connect 1.0 Provider(例如,Google)。OAuth 2.0 Login 实现了这种实现场景:"Login with Google" 或者 "Login with Github" 。

OAuth 2.0 Login 使用 Authorization Code Grant 来实现,就是定义在 OAuth 2.0 Authorization Framework 和 OpenID Connect Core 1.0.

6.7.1 Spring Boot 2.x 示例

Spring Boot 2.x 为 OAuth 2.0 Login 带来了完整的自动配置。

这个章节展示了如何配置 OAuth 2.0 Login 示例,使用 Google 作为 Authentication Provider,并且包含了如下的话题:

初始化设置

使用 Google's OAuth 2.0 认证系统来登录,你必须设置在 Google API 控制台中设置项目来获取 OAuth 2.0 凭证。

Google's OAuth 2.0 实现符合 OpenID 1.0 规范,并且是 OpenID 认证的

跟随 OpenID Connect 页面的配置,从 “Setting up OAuth 2.0” 章节开始。

设置重定向 URI