[In-depth explanation of Spring Security (12)] Use a third-party (Github) to authorize login

(The specific operation of Github authorized login is in the third "Chapter" of the directory)

1. A brief overview of OAuth2

The following is an overview of the book "Introduction to Spring Security":

OAuth is an open standard (now referred to as OAuth generally refers to OAuth2, that is, version 2.0), which can be understood as a protocol that allows users to allow third-party applications to access the user's private resources stored on a website (such as avatars, photos, videos, etc.), and there is no need to provide user names and passwords to third-party applications during this process. This function can be realized by token (token), and each token authorizes a specific website to allow access to specific resources within a specific period of time.

OAuth allows users to authorize third-party websites to flexibly access specific information they store on other resource servers, but not all content. For users, the most common OAuth applications in Internet applications are various third-party logins, such as: QQ authorized login, WeChat authorized login, Github authorized login explained below, etc.

Note: The third-party applications mentioned here are relative terms. For example, a user wants to log in to Toutiao through QQ. At this time, compared to QQ, Toutiao is a third-party application, and for Toutiao, QQ is a third-party application. When Jinri Toutiao logs in through QQ authorization, QQ will not give the user name/password to Jinri Toutiao, but will only pass a token token, allowing it to access some information in QQ users (usually read-only information).

2. The authorization code mode of the four authorization modes of OAuth2

The OAuth2 protocol supports four different authorization modes: 授权码模式, simplified mode, password mode, and client mode. Let me explain the safest and most widely used OAuth2 permission mode - authorization code mode. The following is the authorization flow chart:

insert image description here

  1. When the user clicks the login link (button), the system will import the user to the login page of the authorization server, corresponding to A (User-"Browser-"Authentication Server responds to the browser);
  2. The user chooses whether to grant authorization, and this stage is the user choice authentication stage, corresponding to B.
  3. If the user agrees to the authorization, the authorization server will redirect the page to the address specified by redirect_uri, and at the same time carry an authorization code parameter to redirect with the authorization code. At this time, the token is requested from the authorization server, which is performed on the backend. In Spring Security, it corresponds to the authentication operation, which corresponds to step C.
  4. After the authorization server verifies the parameters, that is, it will return Access Token and Refresh Token after the authentication is successful, that is, Authentication. This process corresponds to E.
  5. After passing the authentication, you can request resources from the resource server.

The authorization code mode is considered to be the safest mode, because the Access Token in this mode does not pass through the browser, but is directly obtained from the backend of the project and sent to the resource server from the backend, which is very large To a certain extent, the risk of Access Token leakage is reduced.

redirect_uri: This parameter indicates that after the login verification succeeds/fails (for example, after the Github verification succeeds or fails), the address to jump to. When jumping, it will also carry the previous authorization code parameter, and the developer can obtain it according to this authorization code. Access Token. The jump address in Spring Security should be /login/oauth2/code/*, * indicates the name of the third-party authorized application, if github authorization is required to log in, then its redirect_uri should be /login/oauth2/code/github.

3. Github authorized login

Preparation

First, you need to register the information of the third-party application on Github. Log in to your Github account and click Settings.

insert image description here
Click New OAuth app to add a new application.
insert image description hereOverview of information to be filled in:

  • application name: application name
  • Homepage URL: Project main page
  • Authorization callback URL: the callback page after successful authentication, the default callback URL address template is {baseUrl}/login/oauth2/code/{registrationId}, where registration is the unique identifier of ClientRegistration, then it will be used in the next SpringBoot project There is no need to provide a callback interface (but it doesn't hurt to write it).

Here's what I tested to register (and click register):

insert image description here
After successful registration, you will get two parameters, Client IDand Client Secret, save these two parameters, which need to be used in the configuration project.

insert image description here

Create a Spring Boot project

  1. required starter dependencies
    insert image description here
  2. Place oauth-Client (application.yml):
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: 57b238e8791efafaead6
            client-secret: 33b3e36f0e464a5c13426fe59e61230ef72a1a47
            redirect-uri: http://localhost:8080/login/oauth2/code/github
server:
  port: 8080
  servlet:
    context-path: /
  1. Create a test interface (TestController)
@RestController
public class TestController {
    
    

    @GetMapping("/test")
    public DefaultOAuth2User test(){
    
    
        System.out.println("Test Result~~~~");
        return (DefaultOAuth2User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }
    
}
  1. Create a SpringSecurity configuration class (SecurityConfig)
@EnableWebSecurity
public class SecurityConfig {
    
    
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    
    
        return http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .oauth2Login()
                .failureHandler((req,res,e)->{
    
    
                    res.setContentType("text/html;charset=utf-8");
                    PrintWriter out = res.getWriter();
                    out.print("认证失败");
                })
                .and()
                .cors()
                .configurationSource(this.corsConfigurationSource())
                .and()
                .csrf((config)->{
    
    
                    config.disable();
                })
                .build();
    }

    private CorsConfigurationSource corsConfigurationSource(){
    
    
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedHeader("*"); // 这个得加上,一些复杂的请求方式会带有header,不加上跨域会失效。
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addExposedHeader("*");
        corsConfiguration.addAllowedOriginPattern("http://localhost:5173");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",corsConfiguration);
        return source;
    }
    
}

Vue test code

Let me mention it again here, otherwise the hyperlink address in the front part will not be understood:

When the backend configuration uses OAuth2Login to authorize login, two filters in Spring Security will be turned on—— OAuth2AuthorizationRequestRedirectFilter, OAuth2LoginAuthenticationFilter. For example: Redirection to the authorization page provided by Github is filtered by OAuth2AuthorizationRequestRedirectFilter; authentication requests and authorization to successfully jump to the URL are filtered by OAuth2LoginAuthenticationFilter.
insert image description hereinsert image description here

So the address I wrote for the authorization login button is: http://localhost:8080/oauth2/authorization/github, OAuth2AuthorizationRequestRedirectFilter will filter it out and then redirect to the authorization page provided by Github...

<script setup>
import {
      
       ref } from 'vue'
import axios from '../utils/index.js'

function test(){
      
      
    axios.get(`/test`,{
      
      
        withCredentials: true,   //设置跨域的时候传递cookie,需要服务端的配合
    }).then(res=>{
      
      
        console.log(res)
        content.value = res
    }).catch(err=>{
      
      
        console.log(666)
        console.log(err)
    })
}

</script>

<template>
    <div>
        <el-button type="info" round>
            <el-link href="http://localhost:8080/oauth2/authorization/github"> github </el-link>
        </el-button>
        <br><br>
        <button @click="test">发送测试请求</button><br><br>
    </div>
</template>

Test effect

This is not the actual effect (the actual effect should be: after clicking the " http://localhost:8080/oauth2/authorization/github" hyperlink, it will return 302 and redirect to the Github authorization page. After the authorization is successful, it will redirect to the configured redirect_uri( http://localhost:8080/login/oauth2/code/github?code=???&state=???). At this time, it is about OAuth2LoginAuthenticationFilter. Now, according to the authorization code code carried in the request parameter in redirect_uri, the access token will be requested from the https://github.com/login/oauth/access_token interface of the Github authorization server. After getting the AccessToken, it will be sent to https:// The api.github.com/user address sends a request to obtain user information, which is visible to the browser in the front, and the token is obtained in the back end, which is invisible to the user).

Please add a picture description
Here are some questions I encountered, ask ChatGpt, if you have the same doubts, you can take a look:

insert image description here
In the middle of the test, there will be a jump to the Github authorization login page (https://github.com/login/oauth/authorize?..), requesting Access Token will also access Github (https://github.com/login/oauth/access_token ), relatively slow, I am impatient and go crazy, and report the following error (don’t learn from me).
insert image description here

Guess you like

Origin blog.csdn.net/qq_63691275/article/details/131351000