欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring?Boot3整合OAuth2實(shí)現(xiàn)第三方登錄功能詳細(xì)示例

 更新時(shí)間:2025年06月19日 09:52:26   作者:MenzilBiz  
OAuth是一個(gè)關(guān)于授權(quán)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),在全世界得到廣泛應(yīng)用,目前的版本是2.0版,這篇文章主要介紹了Spring?Boot3整合OAuth2實(shí)現(xiàn)第三方登錄功能的相關(guān)資料,需要的朋友可以參考下

引言

在當(dāng)今互聯(lián)網(wǎng)應(yīng)用中,第三方登錄已成為提升用戶體驗(yàn)的重要功能。通過集成OAuth2協(xié)議,我們可以讓用戶使用他們已有的社交媒體賬號(hào)(如GitHub、Google、微信等)快速登錄我們的應(yīng)用,而無需創(chuàng)建新的賬號(hào)。本文將詳細(xì)介紹如何在Spring Boot 3應(yīng)用中整合OAuth2實(shí)現(xiàn)第三方登錄功能。

準(zhǔn)備工作

在開始之前,請(qǐng)確保你已經(jīng)具備以下條件:

  • JDK 17或更高版本
  • Spring Boot 3.x項(xiàng)目
  • Maven或Gradle構(gòu)建工具
  • 一個(gè)可用的第三方OAuth2服務(wù)提供商賬號(hào)(如GitHub、Google等)

添加依賴

首先,我們需要在項(xiàng)目中添加Spring Security和OAuth2客戶端依賴:

<dependencies>
    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    <!-- OAuth2 Client -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    
    <!-- Web支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Thymeleaf (可選,用于前端展示) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <!-- Lombok (簡(jiǎn)化代碼) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

配置OAuth2客戶端

application.ymlapplication.properties中配置OAuth2客戶端信息。這里以GitHub為例:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: your-github-client-id
            client-secret: your-github-client-secret
            scope: user:email,read:user
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          github:
            authorization-uri: https://github.com/login/oauth/authorize
            token-uri: https://github.com/login/oauth/access_token
            user-info-uri: https://api.github.com/user
            user-name-attribute: login

server:
  port: 8080
  servlet:
    context-path: /demo

注意:你需要先在GitHub開發(fā)者設(shè)置中創(chuàng)建OAuth應(yīng)用,獲取client-idclient-secret,并設(shè)置正確的回調(diào)URL。

配置安全策略

創(chuàng)建一個(gè)安全配置類來定義我們的安全策略:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // 開發(fā)階段可禁用CSRF
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/login**", "/oauth2/**", "/error**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                .loginPage("/login")
                .defaultSuccessUrl("/home", true)
                .userInfoEndpoint(userInfo -> userInfo
                    .userService(customOAuth2UserService())
                )
                .successHandler(authenticationSuccessHandler())
            )
            .logout(logout -> logout
                .logoutSuccessUrl("/").permitAll()
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
            );
        
        return http.build();
    }

    @Bean
    public OAuth2UserService<OAuth2UserRequest, OAuth2User> customOAuth2UserService() {
        return new CustomOAuth2UserService();
    }

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

自定義OAuth2用戶服務(wù)

我們需要?jiǎng)?chuàng)建一個(gè)自定義的OAuth2用戶服務(wù)來處理用戶信息:

@Slf4j
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User oAuth2User = super.loadUser(userRequest);
        
        String registrationId = userRequest.getClientRegistration().getRegistrationId();
        String accessToken = userRequest.getAccessToken().getTokenValue();
        
        log.info("Registration ID: {}", registrationId);
        log.info("Access Token: {}", accessToken);
        log.info("User Attributes: {}", oAuth2User.getAttributes());
        
        // 根據(jù)不同平臺(tái)處理用戶信息
        Map<String, Object> attributes = new HashMap<>(oAuth2User.getAttributes());
        
        // 添加平臺(tái)標(biāo)識(shí)
        attributes.put("provider", registrationId);
        
        // 標(biāo)準(zhǔn)化用戶信息
        if ("github".equals(registrationId)) {
            attributes.put("email", attributes.get("email") != null ? 
                attributes.get("email") : attributes.get("login") + "@users.noreply.github.com");
        }
        
        return new DefaultOAuth2User(
            Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
            attributes,
            userRequest.getClientRegistration()
                .getProviderDetails()
                .getUserInfoEndpoint()
                .getUserNameAttributeName()
        );
    }
}

自定義認(rèn)證成功處理器

創(chuàng)建一個(gè)認(rèn)證成功處理器來處理登錄成功后的邏輯:

@Slf4j
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, 
                                      HttpServletResponse response,
                                      Authentication authentication) throws IOException {
        
        OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal();
        String provider = (String) oauthUser.getAttribute("provider");
        
        log.info("User logged in from {}: {}", provider, oauthUser.getName());
        
        // 根據(jù)不同的登錄來源處理不同邏輯
        if ("github".equals(provider)) {
            // GitHub特定處理邏輯
            handleGitHubUser(oauthUser);
        }
        
        // 設(shè)置默認(rèn)跳轉(zhuǎn)路徑
        setDefaultTargetUrl("/home");
        super.onAuthenticationSuccess(request, response, authentication);
    }

    private void handleGitHubUser(OAuth2User oauthUser) {
        // 實(shí)現(xiàn)GitHub用戶的特定處理邏輯
        // 例如保存用戶信息到數(shù)據(jù)庫(kù)等
    }
}

創(chuàng)建控制器

添加一些基本的控制器來處理頁(yè)面請(qǐng)求:

@Controller
@RequiredArgsConstructor
public class MainController {

    @GetMapping("/")
    public String home() {
        return "index";
    }

    @GetMapping("/login")
    public String login(Model model) {
        model.addAttribute("providers", List.of("github")); // 可以擴(kuò)展更多提供商
        return "login";
    }

    @GetMapping("/home")
    public String userHome(Principal principal, Model model) {
        if (principal instanceof OAuth2User oauthUser) {
            model.addAttribute("username", oauthUser.getAttribute("name"));
            model.addAttribute("avatar", oauthUser.getAttribute("avatar_url"));
            model.addAttribute("provider", oauthUser.getAttribute("provider"));
        } else {
            model.addAttribute("username", principal.getName());
        }
        return "home";
    }
}

創(chuàng)建前端頁(yè)面

創(chuàng)建幾個(gè)簡(jiǎn)單的Thymeleaf模板頁(yè)面:

src/main/resources/templates/login.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
    <style>
        .oauth-provider {
            display: inline-block;
            margin: 10px;
            padding: 10px 20px;
            background: #f5f5f5;
            border-radius: 5px;
            text-decoration: none;
            color: #333;
        }
        .oauth-provider:hover {
            background: #e5e5e5;
        }
    </style>
</head>
<body>
    <h1>Login with OAuth2</h1>
    <div th:each="provider : ${providers}">
        <a class="oauth-provider" th:href="@{/oauth2/authorization/{provider}(provider=${provider})}" rel="external nofollow" >
            Login with <span th:text="${provider}"></span>
        </a>
    </div>
</body>
</html>

src/main/resources/templates/home.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
    <style>
        .user-info {
            display: flex;
            align-items: center;
            gap: 20px;
            margin-bottom: 20px;
        }
        .avatar {
            width: 80px;
            height: 80px;
            border-radius: 50%;
        }
    </style>
</head>
<body>
    <div class="user-info" th:if="${avatar}">
        <img class="avatar" th:src="${avatar}" alt="User Avatar"/>
        <div>
            <h1>Welcome, <span th:text="${username}"></span>!</h1>
            <p>Logged in via <span th:text="${provider}"></span></p>
        </div>
    </div>
    
    <div th:unless="${avatar}">
        <h1>Welcome, <span th:text="${username}"></span>!</h1>
    </div>
    
    <form th:action="@{/logout}" method="post">
        <button type="submit">Logout</button>
    </form>
</body>
</html>

測(cè)試應(yīng)用

  • 啟動(dòng)應(yīng)用并訪問http://localhost:8080/demo/login
  • 點(diǎn)擊"Login with GitHub"按鈕
  • 你將被重定向到GitHub進(jìn)行授權(quán)
  • 授權(quán)后,你會(huì)被重定向回應(yīng)用并顯示歡迎信息和用戶頭像

擴(kuò)展功能

  • 多提供商支持:添加Google、Facebook等提供商:

    spring:
      security:
        oauth2:
          client:
            registration:
              google:
                client-id: your-google-client-id
                client-secret: your-google-client-secret
                scope: email,profile
    
  • 用戶信息持久化:創(chuàng)建用戶實(shí)體和Repository:

    @Entity
    @Data
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String provider;
        private String providerId;
        private String name;
        private String email;
        private String avatarUrl;
        private LocalDateTime createdAt = LocalDateTime.now();
    }
    
  • JWT集成:結(jié)合OAuth2和JWT實(shí)現(xiàn)無狀態(tài)認(rèn)證。

常見問題解決

  • 重定向URI不匹配

    • 確保在OAuth提供商后臺(tái)配置的回調(diào)URL與應(yīng)用中的一致
    • 格式通常為:http://localhost:8080/demo/login/oauth2/code/github
  • CSRF問題

    • 生產(chǎn)環(huán)境應(yīng)啟用CSRF保護(hù)
    • 確保表單提交包含CSRF令牌
  • 范圍不足

    • 檢查請(qǐng)求的scope是否正確
    • 某些提供商需要審核才能獲取高級(jí)權(quán)限

總結(jié)

本文詳細(xì)介紹了在Spring Boot 3中整合OAuth2實(shí)現(xiàn)第三方登錄的完整流程。通過Spring Security的OAuth2客戶端支持,我們可以輕松集成多種第三方登錄提供商。關(guān)鍵點(diǎn)包括:

  • 正確配置OAuth2客戶端信息
  • 自定義用戶服務(wù)處理不同提供商的用戶信息
  • 實(shí)現(xiàn)認(rèn)證成功處理器處理登錄后邏輯
  • 提供友好的用戶界面

你可以在此基礎(chǔ)上擴(kuò)展更多功能,如用戶信息持久化、多提供商支持、JWT集成等。希望這篇文章對(duì)你實(shí)現(xiàn)第三方登錄功能有所幫助!

到此這篇關(guān)于Spring Boot3整合OAuth2實(shí)現(xiàn)第三方登錄功能的文章就介紹到這了,更多相關(guān)SpringBoot3整合OAuth2第三方登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解JAVA中implement和extends的區(qū)別

    詳解JAVA中implement和extends的區(qū)別

    這篇文章主要介紹了詳解JAVA中implement和extends的區(qū)別的相關(guān)資料,extends是繼承接口,implement是一個(gè)類實(shí)現(xiàn)一個(gè)接口的關(guān)鍵字,需要的朋友可以參考下
    2017-08-08
  • 解決mybatis 數(shù)據(jù)庫(kù)date 與 java中Date類型映射問題

    解決mybatis 數(shù)據(jù)庫(kù)date 與 java中Date類型映射問題

    這篇文章主要介紹了解決mybatis 數(shù)據(jù)庫(kù)date 與 java中Date類型映射問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來吧
    2020-11-11
  • Java 面試題和答案 - (下)

    Java 面試題和答案 - (下)

    本文主要介紹Java 面試題,這里整理了Java面試題關(guān)于JDBC,線程異常處理,Servlet,JSP的知識(shí)的整理,幫助大家理解知識(shí)點(diǎn),便于面試,有興趣的小伙伴可以參考下
    2016-09-09
  • Spring中IOC和AOP的深入講解

    Spring中IOC和AOP的深入講解

    這篇文章主要給大家介紹了關(guān)于Spring中IOC和AOP的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • spring boot org.junit.jupiter.api不存在的解決

    spring boot org.junit.jupiter.api不存在的解決

    這篇文章主要介紹了spring boot org.junit.jupiter.api不存在的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring Boot打包部署和環(huán)境配置詳解

    Spring Boot打包部署和環(huán)境配置詳解

    這篇文章主要介紹了Spring Boot打包部署和環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 解決SpringBoot配置文件項(xiàng)目重啟出現(xiàn)亂碼的問題

    解決SpringBoot配置文件項(xiàng)目重啟出現(xiàn)亂碼的問題

    最近在創(chuàng)建了SpringBoot項(xiàng)目后往配置文件中寫了相關(guān)的系統(tǒng)配置,并且在上面加了中文注釋,但是在重啟項(xiàng)目或開機(jī)重啟后遇到了注釋亂碼的情況,下面這篇文章主要給大家介紹一下如何解決SpringBoot配置文件項(xiàng)目重啟出現(xiàn)亂碼的問題,需要的朋友可以參考下
    2023-06-06
  • Springboot接收文件與發(fā)送文件實(shí)例教程

    Springboot接收文件與發(fā)送文件實(shí)例教程

    最近工作中遇到個(gè)需求,springboot簡(jiǎn)單的上傳文檔或者圖片,并且進(jìn)行操作,操作完后進(jìn)行保存指定路徑,下面這篇文章主要給大家介紹了關(guān)于Springboot接收文件與發(fā)送文件的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • 解析Java的Spring框架的基本結(jié)構(gòu)

    解析Java的Spring框架的基本結(jié)構(gòu)

    這篇文章主要介紹了Java的Spring框架的基本結(jié)構(gòu),作者從Spring的設(shè)計(jì)角度觸發(fā)解析其基礎(chǔ)的架構(gòu)內(nèi)容,需要的朋友可以參考下
    2016-03-03
  • java8 Stream API之reduce使用說明

    java8 Stream API之reduce使用說明

    這篇文章主要介紹了java8 Stream API之reduce使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評(píng)論