3 Star 1 Fork 2

heguangchuan / spring-authorization-server

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
README-login.md 7.90 KB
一键复制 编辑 原始数据 按行查看 历史

概述

本文参考来源:

Spring Security提供了全面的OAuth 2支持。本节讨论了如何将OAuth 2集成到你的基于Servlet的应用程序中。 OAuth 2.0登录功能允许应用程序让用户通过使用他们在OAuth 2.0提供商(如GitHub)或OpenID Connect 1.0提供商(如Google)的现有账户登录到应用程序

依赖引入

想要实现通过 OAuth 2.0提供商的现有账户登录到应用程序需要引入 oauth2-client ,下面按照官网给的默认配置进行深入

<dependencies>
    <!--引入oauth2-client:通过 OAuth 2.0提供商的现有账户登录到应用程序-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>

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

application.yml

以 Google 为例,想要通过 Google 的现有账户进行登录,需要进行下面的配置,spring security 团队为一些知名的供应商预先定义了一套默认的客户端属性。如:谷歌、GitHub、Facebook和Okta, 按照官网提供的配置进行配置即可

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: google-client-id
            client-secret: google-client-secret

这里只做一个示范,国内你也根本不可能访问到 google,因此上面的 client-id 和 client-secret 不需要换成真实的。启动程序,访问 http://localhost:8080/login 会发现页面给了一个 去 google 的链接,之后就是 google 基于 oauth2 的授权码模式流程,这里不做过多介绍。

Image

当然,你的系统可以支持多个oauth2应用的供应商提供的登录方式,有些供应商不在 spring security 团队的计划内,需要自己适配,只需要将各个属性都配置即可

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: google-client-id
            client-secret: google-client-secret
          github:
            client-id: github-client-id
            client-secret: github-client-secret
          gitee:
            provider: gitee
            client-id: gitee-client-id
            client-secret: gitee-client-secret
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            scope: user_info
            client-name: Gitee
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-name-attribute: id
            user-info-uri: https://gitee.com/api/v5/user

比如:像配置文件中的 gitee 就需要按照上面的方式进行配置,再次启动程序 就可以看到,可以用 google , github , gitee 进行登录了

实战案例

由于国内 github 、 facebook、 google 等龟速问题,我们以 gitee 为例进行 oauth2 登录的演示,其实就是对前面整个章节的一个示范,这里只是引入了 一个 oauth2-client 的依赖而已。

gitee 的有关 oauth2 授权的开发者文档: https://gitee.com/api/v5/oauth_doc#/

创建 gitee 应用

根据上面的链接,创建好gitee的应用即可,不做赘述,主要是获取 clientId 及 client Secret,将获取的信息配置到 application.yml 中即可

spring:
  security:
    oauth2:
      client:
        registration:
          gitee:
            provider: gitee
            client-id: gitee-client-id
            client-secret: gitee-client-secret
            ## 使用授权码模式
            authorization-grant-type: authorization_code
            ## 配置在 gitee 上的回调地址 务必保持一致,如果是想对第三方应用的用户进行处理
            ## 请将回调地址配置成 '{baseUrl}/login/oauth2/code/{registrationId}' 模式
            redirect-uri: https://www.baidu.com
            ## 授权范围
            scope:
              - user_info
            client-name: Gitee
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-name-attribute: id
            user-info-uri: https://gitee.com/api/v5/user

启动程序,访问 http://localhost:8080/login ,点击 Gitee ,系统将引导你到 gitee 的授权页面

Image

接下来的事情就不再赘述了

处理用户信息

HttpSecurity.oauth2Login() 为定制OAuth 2.0登录提供了大量的配置选项。主要的配置选项被分组到它们的协议端点对应处。 例如,oauth2Login().authorizationEndpoint() 允许配置授权端点,而 oauth2Login().tokenEndpoint() 允许配置令牌端点。 在用户成功通过 OAuth 2.0 提供商的认证后,OAuth2User.getAuthorities()(或 OidcUser.getAuthorities())包含一个 由 OAuth2UserRequest.getAccessToken().getScopes() 填充的授予权限列表,其前缀为 SCOPE_。 这些授权可以被映射到一组新的 GrantedAuthority 实例中,在完成认证时提供给 OAuth2AuthenticationToken。

https://docs.spring.io/spring-security/reference/servlet/oauth2/login/advanced.html#oauth2login-advanced-oauth2-user-service

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.SecurityFilterChain;

import java.util.Map;

@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .oauth2Login(oauth2 -> oauth2
                        .userInfoEndpoint(userInfo -> userInfo
                                .userService(this.oauth2UserService())));
        return http.build();
    }

    private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
        DefaultOAuth2UserService userService = new DefaultOAuth2UserService(){
            @Override
            public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
                //假设这里要将用户存到数据库
                OAuth2User oAuth2User = super.loadUser(userRequest);
                //userRequest 和 oAuth2User 中有大量的有用信息可以拿来使用 具体断点到这里看就行了
                //1 写个方法将 oAuth2User 和 userRequest 中有用的信息 转化成系统用户
                //2 将系统用户存入数据库
                Map<String, Object> attributes = oAuth2User.getAttributes();
                //3 可以在这里自定义一些信息放入 attributes 中
                return new DefaultOAuth2User(oAuth2User.getAuthorities(),attributes,userRequest
                        .getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
            }
        };

        return userService;
    }
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/heguangchuan/spring-authorization-server.git
git@gitee.com:heguangchuan/spring-authorization-server.git
heguangchuan
spring-authorization-server
spring-authorization-server
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891