Spring Security整合Gitee第三方登录

news2024/11/24 14:02:48

文章目录

  • 学习链接
  • 环境准备
    • 1. 搭建基本web应用
      • 引入依赖
      • ThirdApp启动类
      • 创建index页面
      • application.yml配置
      • 访问测试
    • 2. 引入security
      • 引入依赖
      • ProjectConfig
      • 访问测试
  • 第三方认证
    • 简介
    • 注册gitee客户端
    • 实现1
      • 引入依赖
      • application.yml配置文件
      • 创建index.html页面
      • 启动类
      • InfoController
      • ProjectConfig
      • GiteeClient
      • 访问测试
    • 实现2
      • 引入依赖
      • application.yml配置文件
      • 创建index.html页面
      • 启动类
      • InfoController
      • ProjectConfig

学习链接

Security OAuth2 授权 & JWT - 自己总结

OAuth2的授权流程和源码分析 - 自己总结

SpringSecurity(十七)—OAuth2的运行机制(下)-实现一个简单的单点登录应用程序

springsecurity加入第三方授权认证

SpringBoot+Vue实现第三方Gitee登录(一)

SpringBoot+Vue实现第三方Gitee登录(二)

第三方登录专栏 - 比较全very good

【OAuth2.0 Client 总结】对接github第三方登录以及其他第三方登录总结

Spring oauth2 authorization server示例项目
Spring Authorization Server - 专栏

Spring Boot+OAuth2,一个注解搞定单点登录! - 已下载pdf到笔记文件夹,有时间就看看,包括代码已fork到gitee

SpringSecurity(十四)—实现过滤器(下)整合短信认证

环境准备

全部代码Gitee地址

1. 搭建基本web应用

目录结构如下

在这里插入图片描述

引入依赖

暂时只引入spring-boot-starter-web启动器

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>demo-spring-security-third</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-boot-version>2.3.3.RELEASE</spring-boot-version>
        <spring-cloud-version>Greenwich.RELEASE</spring-cloud-version>
    </properties>

    <dependencies>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.interceptor</groupId>
                <artifactId>javax.interceptor-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-jwt</artifactId>
                <version>1.1.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security.oauth.boot</groupId>
                <artifactId>spring-security-oauth2-autoconfigure
                </artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot-version}</version>
                <configuration>
                    <!--<mainClass>com.tuling.springbootsecurity.SpringBootSecurityApplication</mainClass>-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

ThirdApp启动类

@SpringBootApplication
public class ThirdApp {

    public static void main(String[] args) {
        SpringApplication.run(ThirdApp.class, args);
    }

}

创建index页面

在resources/static目录下,创建index.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>

application.yml配置

server:
  port: 9090

访问测试

能访问到如下页面,就算成功

在这里插入图片描述

2. 引入security

页面结构如下

在这里插入图片描述

引入依赖

在上面的基础上,添加security依赖,如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>demo-spring-security-third</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-boot-version>2.3.3.RELEASE</spring-boot-version>
        <spring-cloud-version>Greenwich.RELEASE</spring-cloud-version>
    </properties>

    <dependencies>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.interceptor</groupId>
                <artifactId>javax.interceptor-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-jwt</artifactId>
                <version>1.1.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security.oauth.boot</groupId>
                <artifactId>spring-security-oauth2-autoconfigure
                </artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot-version}</version>
                <configuration>
                    <!--<mainClass>com.tuling.springbootsecurity.SpringBootSecurityApplication</mainClass>-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

ProjectConfig

@Configuration
@EnableWebSecurity
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    	/* 配置表单登录 */
    	/* 1. 如果不添加上表单登录, 那么直接访问:localhost:9090 会显示403的白页, 
    	      这是因为ExceptionTranslationFilter此时用的authenticationEntryPoint的类型是: Http403ForbiddenEntryPoint

           2. 如果添加上表单登录, 那么直接访问:localhost:9090, 就会重定向到登录表单页, 
    	      这是因为在AbstractAuthenticationFilterConfigurer中, 会使用LoginUrlAuthenticationEntryPoint, 
    	      然后设置给ExceptionTranslationFilter的authenticationEntryPoint属性 。

			  同时, FormLoginConfigurer也会影响到DefaultLoginPageGeneratingFilter的配置, 
			       在FormLoginConfigurer的initDefaultLoginFilter中会把DefaultLoginPageGeneratingFilter的formEnabled属性设置为true, 而开启登录页

           3. 如果添加上表单登录, security会自动给http.authorizeRequests()对: 登录页、登录请求处理、登录失败这些路径 放开, 全部允许它们被访问。
		      这在AbstractAuthenticationFilterConfigurer的init方法中调用updateAccessDefaults有体现,
		      同时再参考下: ExpressionUrlAuthorizationConfigurer类种的REGISTRY属性、
		                  ExpressionUrlAuthorizationConfigurer的createMetadataSource方法
              就能明白了。
              
           4. 我觉得security难就难在这些地方, 
              通过不同配置器添加不同的过滤器, 配置器又能获取到其它配置器的属性或共享属性来更改过滤器的配置, 
              反正就是各种都能改, 你也不知道它默认的行为会怎么改, 
              你还得知道它的配置器的执行顺序, 虽然过滤器的顺序是早已固定的定义在FilterComparator中,
              这样的话, 如果不看源码, 只是看它的文档介绍怎么使用, 就很难办。
              不过, 这样也会让它变得很灵活, 反正就是可以各种自定义, 各种配置都可以按自己的来实现,
 	    */
        http.formLogin();
        
		/* 访问任何资源都需要认证 */
        http.authorizeRequests().anyRequest().authenticated();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        HashMap<String, PasswordEncoder> encoders = new HashMap<>();
       
        encoders.put("bcrypt", new BCryptPasswordEncoder());
      
        return new DelegatingPasswordEncoder("bcrypt", encoders);
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            if ("zzhua".equals(username)) {
                return new User("zzhua", passwordEncoder().encode("zzhua"), AuthorityUtils.createAuthorityList("admin"));
            }
            return null;
        };
    }
}

访问测试

  1. 访问: localhost:9090 时,会被重定向到:http://localhost:9090/login 表单登录界面
    在这里插入图片描述

  2. 在表单登录界面输入用户名和密码,点击登录,跳转到主页:http://localhost:9090/
    在这里插入图片描述

第三方认证

简介

当前我们系统是有自己的一套用户体系的,在前面通过security搭建了1个非常简单的登录示例。可是,用户要登录我们的系统,需要先注册账号,然后填写一大堆表单,包括:用户名、密码、验证码、性别、年龄、上传头像、绑定邮箱、绑定手机号等等一大堆,这就增加了用户使用我们系统的成本。

因此可以使用比较可靠的第三方系统的用户身份登录我们的系统,但用户仍然是第三方系统的用户只是用户可以授权他在第三方系统的权限给我们系统,让我们系统可以访问这个用户在第三方系统中的用户信息、用户资源等

这样用户只需要授权他在第三方用户系统中的资源给我们系统即可,而不需要填写或以后再填写其它信息的登录方式,降低用户注册的成本,就是第三方登录。

当然,拿到用户在第三方系统中的用户身份信息之后,我们可以自己生成这个用户的账号,然后使用这个用户的账号绑定 这个用户在第三方系统中的唯一id,等到用户他下次再使用第三方系统登录我们系统的时候,就可以查询到他之前是否已经使用第三方系统账号登录我们系统了,如果登陆过,则把这个账号查出来,继续使用。如果没查询出来,则生成1个账号,并绑定第三方系统用户唯一id,并且也可以设置默认密码,或当用户设置密码时,才允许使用账号、密码 登录我们系统

注册gitee客户端

首先,需要明白:是gitee的用户 向 gitee认证服务器 请求授权给 我们系统 访问 该gitee用户在gitee中的用户资源。这里面用的是授权码模式

我们系统对于gitee来说,属于客户端。gitee需要知道用户请求授权给的系统的身份。假设gitee知道我们系统是个黑网站,gitee就肯定就直接拉黑我们系统了,肯定就不允许gitee的用户授权给我们系统了,因此,gitee会对需要接入它的用户的客户端进行管理。因此,我们需要在gitee上注册为客户端。

在这里插入图片描述

实现1

引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>demo-spring-security-third</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-boot-version>2.3.3.RELEASE</spring-boot-version>
        <spring-cloud-version>Greenwich.RELEASE</spring-cloud-version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
      
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.interceptor</groupId>
                <artifactId>javax.interceptor-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-jwt</artifactId>
                <version>1.1.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security.oauth.boot</groupId>
                <artifactId>spring-security-oauth2-autoconfigure
                </artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot-version}</version>
                <configuration>
                    <!--<mainClass>com.tuling.springbootsecurity.SpringBootSecurityApplication</mainClass>-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml配置文件

server:
  port: 9090

创建index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>

启动类

@SpringBootApplication
public class ThirdApp {

    public static void main(String[] args) {
        SpringApplication.run(ThirdApp.class, args);
    }

}

InfoController

@RestController
public class InfoController {

    /* 只能使用第三方登录的用户, 才能访问此接口, 否则会由于参数类型不对绑定不上去而报错 */
    @GetMapping("info")
    public String info(OAuth2AuthenticationToken token) {
        System.out.println(token.getPrincipal());
        return "ok";
    }

}

ProjectConfig

@Configuration
@EnableWebSecurity
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private GiteeClient giteeClient;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
        http.oauth2Login(c->c.clientRegistrationRepository(clientRegistrationRepository()));

        http.formLogin();
        http.authorizeRequests().anyRequest().authenticated();
    }

    private ClientRegistrationRepository clientRegistrationRepository(){
        return new InMemoryClientRegistrationRepository(giteeClient.clientRegistration());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        HashMap<String, PasswordEncoder> encoders = new HashMap<>();
        encoders.put("bcrypt", new BCryptPasswordEncoder());
        return new DelegatingPasswordEncoder("bcrypt", encoders);
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            if ("zzhua".equals(username)) {
                return new User("zzhua", passwordEncoder().encode("zzhua"), AuthorityUtils.createAuthorityList("admin"));
            }
            return null;
        };
    }
}

GiteeClient

@Component
public class GiteeClient {

	public ClientRegistration clientRegistration(){
		return ClientRegistration.withRegistrationId("gitee")  //起个名字,代表client,如clientId和clientSecret
				.clientId("XXX")  //此处要换成你在gitee上创建应用得到的
				.clientSecret("YYY") //此处要换成你在gitee上创建应用得到的
				.scope(new String[]{"user_info"})    //读取用户权限,参见你gitee上创建应用时的授权勾选
				.authorizationUri("https://gitee.com/oauth/authorize")   //这要看gitee的api,是user认证以及client认证获取授权码的地址
				.tokenUri("https://gitee.com/oauth/token") //这要看gitee的api,是client得到授权码后去换token的gitee地址
				.userInfoUri("https://gitee.com/api/v5/user") //资源服务器api地址-也是client用access-token去获取用户user详情的“用户详情资源服务器地址”-这里也是gitee】】
				.userNameAttributeName("id")
				.clientName("gitee")  //为我们的应用client起了个名字
				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)  //注是授权码模式
				.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")  //本应用配置的gitee发回授权码的地址
				.build();
	}
}

访问测试

  1. 访问:localhost:9090 后,被重定向到 http://localhost:9090/oauth2/authorization/gitee 这个地址,然后这个地址又自动被重定向到:https://gitee.com/oauth/authorize?response_type=code&client_id=7b3ed41b0138556c3e1c39089ef2fb2f1b1b9d06ecc65002472348c9fc9b9e95&scope=user_info&state=aHG4a0a1nCi3jOVQm2aLoGbrLVl8V-zRffgDmXgvj4M%3D&redirect_uri=http://localhost:9090/login/oauth2/code/gitee这个gitee的授权页面,
    但是,由于我没有登录,所以又被重定向到https://gitee.com/login?redirect_to_url=https%3A%2F%2Fgitee.com%2Foauth%2Fauthorize%3Fresponse_type%3Dcode%26client_id%3D7b3ed41b0138556c3e1c39089ef2fb2f1b1b9d06ecc65002472348c9fc9b9e95%26scope%3Duser_info%26state%3DaHG4a0a1nCi3jOVQm2aLoGbrLVl8V-zRffgDmXgvj4M%253D%26redirect_uri%3Dhttp%3A%2F%2Flocalhost%3A9090%2Flogin%2Foauth2%2Fcode%2Fgitee这个gitee的登录地址,登录页面如下:
    在这里插入图片描述

  2. 填入gitee的用户名和密码,点击登录,它会把表单数据发送到登录请求接口: https://gitee.com/login,并携带用户名和密码。如果登录成功,则会重定向到:https://gitee.com/oauth/authorize?response_type=code&client_id=7b3ed41b0138556c3e1c39089ef2fb2f1b1b9d06ecc65002472348c9fc9b9e95&scope=user_info&state=aHG4a0a1nCi3jOVQm2aLoGbrLVl8V-zRffgDmXgvj4M%3D&redirect_uri=http://localhost:9090/login/oauth2/code/gitee授权页面,请求用户授权
    在这里插入图片描述

  3. 如果用户点击拒绝,会对gitee的授权接口发起请求:https://gitee.com/oauth/authorize,并携带表单数据。然后gitee服务器发现当前用户拒绝授权给我们系统,就会让浏览器重定向到:http://localhost:9090/login/oauth2/code/gitee?error=access_denied&error_description=%E7%94%A8%E6%88%B7%E6%88%96%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8B%92%E7%BB%9D%E4%BA%86%E8%AF%B7%E6%B1%82&state=aHG4a0a1nCi3jOVQm2aLoGbrLVl8V-zRffgDmXgvj4M%3D ,然后又自动重定向到:http://localhost:9090/login?error 了,此时,页面如下:
    在这里插入图片描述

  4. 如果用户点击同意,会对gitee的授权接口发起请求:https://gitee.com/oauth/authorize,并携带表单数据。然后gitee服务器发现当前用户同意授权给我们系统,就会让浏览器重定向到:http://localhost:9090/login/oauth2/code/gitee?code=c3944aa307153828e80efee311151b925ff6f8d4e6c35850ed2ebe4e665f6f1f&state=b1X4XuCXNF50zmbY3HiXInh0inHsPXhGgH2pOZ9xliE%3D,看里面是携带了code授权码和state的,然后又自动重定向到:http://localhost:9090/了,此时,页面如下:
    在这里插入图片描述

  5. 访问:http://localhost:9090/info,此时页面如下:在这里插入图片描述
    控制台打印的数据如下:

    Name: [5029907], 
    Granted Authorities: [[ROLE_USER, SCOPE_emails, SCOPE_enterprises, SCOPE_gists, SCOPE_groups, SCOPE_hook, SCOPE_issues, SCOPE_keys, SCOPE_notes, SCOPE_projects, SCOPE_pull_requests, SCOPE_user_info]], 
    User Attributes: [
    {id=5029907, 
    login=zzhua195, 
    name=zzhua, avatar_url=https://gitee.com/assets/no_portrait.png, url=https://gitee.com/api/v5/users/zzhua195, html_url=https://gitee.com/zzhua195, 
    remark=, followers_url=https://gitee.com/api/v5/users/zzhua195/followers, 
    following_url=https://gitee.com/api/v5/users/zzhua195/following_url{/other_user}, 
    gists_url=https://gitee.com/api/v5/users/zzhua195/gists{/gist_id}, 
    starred_url=https://gitee.com/api/v5/users/zzhua195/starred{/owner}{/repo}, 
    subscriptions_url=https://gitee.com/api/v5/users/zzhua195/subscriptions, 
    organizations_url=https://gitee.com/api/v5/users/zzhua195/orgs, 
    repos_url=https://gitee.com/api/v5/users/zzhua195/repos, 
    events_url=https://gitee.com/api/v5/users/zzhua195/events{/privacy}, 
    received_events_url=https://gitee.com/api/v5/users/zzhua195/received_events, 
    type=User, 
    blog=null, weibo=null, bio=null, 
    public_repos=301, 
    public_gists=0, 
    followers=4, following=17, stared=133, 
    watched=415, 
    created_at=2019-05-23T10:19:09+08:00, 
    updated_at=2024-05-19T16:59:39+08:00, email=null}
    ]
    
  6. 清空浏览器的所有缓存,访问:http://localhost:9090/login,会来到我们系统自己的登录页,输入用户凭据后,点击登录
    在这里插入图片描述
    在这里插入图片描述
    此时,再去访问:http://localhost:9090/info,会返回500的错误页面,因为当前用户类型并不是通过第三方gitee来登录的。

实现2

只是将代码配置改成配置文件配置

引入依赖

与上面一致

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zzhua</groupId>
    <artifactId>demo-spring-security-third</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-boot-version>2.3.3.RELEASE</spring-boot-version>
        <spring-cloud-version>Greenwich.RELEASE</spring-cloud-version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
       
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
      
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.interceptor</groupId>
                <artifactId>javax.interceptor-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-jwt</artifactId>
                <version>1.1.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security.oauth.boot</groupId>
                <artifactId>spring-security-oauth2-autoconfigure
                </artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot-version}</version>
                <configuration>
                    <!--<mainClass>com.tuling.springbootsecurity.SpringBootSecurityApplication</mainClass>-->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml配置文件

server:
  port: 9090
spring:
  security:
    oauth2:
      client:
        registration:
          gitee:
            client-id: YOUR_ID
            client-secret: YOUR_SECRET
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/{action}/oauth2/code/{registrationId}'
            client-name: gitee
            provider: gitee
            scope:
              - user_info
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-info-uri: https://gitee.com/api/v5/user
            user-name-attribute: id

创建index.html页面

与上面一致

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>

启动类

与上面一致

@SpringBootApplication
public class ThirdApp {

    public static void main(String[] args) {
        SpringApplication.run(ThirdApp.class, args);
    }

}

InfoController

与上面一致

@RestController
public class InfoController {

    /* 只能使用第三方登录的用户, 才能访问此接口, 否则会由于参数类型不对绑定不上去而报错 */
    @GetMapping("info")
    public String info(OAuth2AuthenticationToken token) {
        System.out.println(token.getPrincipal());
        return "ok";
    }

}

ProjectConfig

@Configuration
@EnableWebSecurity
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.oauth2Login();

        http.formLogin();
        http.authorizeRequests().anyRequest().authenticated();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        HashMap<String, PasswordEncoder> encoders = new HashMap<>();
        encoders.put("bcrypt", new BCryptPasswordEncoder());
        return new DelegatingPasswordEncoder("bcrypt", encoders);
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            if ("zzhua".equals(username)) {
                return new User("zzhua", passwordEncoder().encode("zzhua"), AuthorityUtils.createAuthorityList("admin"));
            }
            return null;
        };
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1689919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html中table表格的行、列怎么进行合并

在HTML中&#xff0c;使用 <table> 元素来创建表格&#xff0c;而行&#xff08;tr&#xff09;和列&#xff08;td或th&#xff09;的合并可以通过 colspan和 rowspan 属性来实现。这两个属性允许单个表格单元格&#xff08;td或th&#xff09;跨越多个列或行。 colspa…

【FixBug】超级大Json转POJO失败

今天遇到了一个问题&#xff1a;使用Jackson将一个超级大的JSON字符串转换POJO失败&#xff0c;debug看没问题&#xff0c;将JSON字符串粘贴到main方法中测试&#xff0c;提示错误信息如下&#xff1a; 自己猜测是因为字符串超长导致转换时先截断字符串导致JSON格式不正确&…

QT5.15.2及以上版本安装

更新时间&#xff1a;2024-05-20 安装qt5.15以上版本 系统&#xff1a;ubuntu20.04.06 本文安装&#xff1a;linux-5.15.2 下载安装 # 安装编译套件g sudo apt-get install build-essential #安装OpenGL sudo apt-get install libgl1-mesa-dev# 下载qt安装器 https://downl…

安卓 逆向高级-人均瑞数

引言&#xff1a; JS 爬虫&#xff0c;绕不过瑞数这道坎&#xff0c;卡的死死的。一般网上的教程就是补环境什么的&#xff0c;我尝试了&#xff0c;可以但是比较麻烦。 今天说一种&#xff0c;秒过的方式&#xff0c;抗并发。那就是牛逼的RPC&#xff0c;hook JS 技术。 前期…

RedisTemplateAPI:List

文章目录 ⛄介绍⛄List的常见命令有⛄RedisTemplate API❄️❄️添加缓存❄️❄️将List放入缓存❄️❄️设置过期时间(单独设置)❄️❄️获取List缓存全部内容&#xff08;起始索引&#xff0c;结束索引&#xff09;❄️❄️从左或从右弹出一个元素❄️❄️根据索引查询元素❄…

【日记】跟奇安信斗智斗勇,败下阵来(416 字)

正文 今天一个客户都没有&#xff0c;让我快怀疑我们银行是不是要倒闭了…… 因为内外网 u 盘不知所踪&#xff0c;所以重新制了一个。深刻体会到了奇安信有多烂。有两个 u 盘&#xff0c;奇安信似乎把主控写坏了&#xff0c;插上电脑有反应&#xff0c;但是看不见盘符&#xf…

游戏陪玩/在线租号/任务系统网站源码

源码介绍 游戏陪玩系统/在线租号系统/小姐姐陪玩任务系统/网游主播任务威客平台源码/绝地吃鸡LOL在线下单/带手机端/声优线上游戏任务系统网站源码 界面美观,功能齐全,已对接支付,安装教程放源码压缩包里了! 界面截图 源码下载 https://download.csdn.net/download/huayula…

【Fiddler抓包工具】第四节.断点设置和弱网测试

文章目录 前言一、断点设置 1.1 全局断点 1.2 局部断点 1.3 打断点的几种常用命令 1.4 篡改响应报文二、弱网测试 2.1 网络限速 2.2 精准限速总结 前言 一、断点设置 1.1 全局断点 特点&#xff1a; 中断Fiddler捕获的所有请求&#xff0c;包括…

系统架构师考试(九)

TCP/IP协议族 SMTP是简单邮件传输协议 DNS 域名解析协议 URL - IP&#xff0c;通过URL解析ip是哪一台电脑 DHCP 动态IP地址分配的协议 SNMP 简单网络管理协议 TFTP 简单文件管理协议 ICMP 是网络中差错校验&#xff0c;差错报错的协议 IGMP G是组&#xff0c;组…

cuda11.2安装哪个版本的tensorflow-gpu

在官网上找到这个表格&#xff0c;因为自己的电脑一直配置的11.2的cuda&#xff0c;所以也不想换&#xff0c;最好就是安装一般能适应该版本的tensorflow&#xff0c;我配置了python3.8的环境&#xff0c;然后进行 pip install tensorflow-gpu2.6 回车就会自动从清华镜像上进…

基于vue3速学angular

因为工作原因&#xff0c;需要接手新的项目&#xff0c;新的项目是angular框架的&#xff0c;自学下和vue3的区别&#xff0c;写篇博客记录下&#xff1a; 参考&#xff1a;https://zhuanlan.zhihu.com/p/546843290?utm_id0 1.结构上&#xff1a; vue3:一个vue文件&#xff…

金职优学:分析央国企面试如何通关?

在当今竞争激烈的就业市场中&#xff0c;中央和国有企业&#xff08;以下简称“央国企”&#xff09;的面试机会对求职者来说是非常有吸引力的。这些企业通常拥有稳定的发展前景、良好的薪酬福利和广阔的职业发展空间。但是&#xff0c;要想成功通过央国企的面试&#xff0c;求…

力扣HOT100 - 31. 下一个排列

解题思路&#xff1a; 数字是逐步增大的 步骤如下&#xff1a; class Solution {public void nextPermutation(int[] nums) {int i nums.length - 2;while (i > 0 && nums[i] > nums[i 1]) i--;if (i > 0) {int j nums.length - 1;while (j > 0 &&…

2024年二建准考证打印入口已开通!

24年二建将于6月1日、2日举行&#xff0c;目前西藏、陕西准考证打印入口已开通&#xff0c;各省也将陆续开始准考证打印工作。 2024二建考试时间安排 2024二建准考证打印时间 二建准考证打印须知 01 准考证打印信息显示空白怎么办? 1)使用电脑自带的浏览器重新试一下。 2)…

【全开源】填表统计预约打卡表单系统FastAdmin+ThinkPHP+UniApp

简化流程&#xff0c;提升效率 一、引言&#xff1a;传统表单处理的局限性 在日常工作和生活中&#xff0c;我们经常会遇到需要填写表单、统计数据和预约打卡等场景。然而&#xff0c;传统的处理方式往往效率低下、易出错&#xff0c;且不利于数据的统计和分析。为了解决这些…

Spring Web MVC介绍及详细教程

目录 1.什么是Spring Web MVC&#xff1f; 1.1 MVC定义 1.2 Spring MVC与MVC关系 2.为什么要学习Spring MVC 3.项目创建 4.Spring MVC连接 4.1 RequestMapping 4.2 PostMapping和GetMapping 5.Spring MVC参数获取 5.1 获取单个参数 5.2 获取多个参数 5.3 获取普通对…

Web3 游戏平台 Creo Engine 销毁代币总量的20%,以促进长远发展

Creo Engine 5月16日进行了第三次代币销毁&#xff0c;这次的销毁占代币总量的 20%。一共销毁了2亿 $CERO 代币&#xff0c;市场价值接近 2000 万美元。 Creo Engine 致力于连接世界、为玩家提供一站式游戏中心&#xff0c;并提升 Web3 游戏体验。 Creo Engine 发布于2022年&am…

springboot集成达梦数据库8,用springboot+mtbatisplus查询值为空

springboot集成达梦数据库8&#xff0c;用springbootmtbatisplus查询值为空 背景&#xff1a;springboot集成达梦数据库8&#xff0c;用springbootmtbatisplus查询值为空&#xff0c;但是在DB管理工具中是可以查询到数据的。 原因及解决方法&#xff1a;执行添加语句后&#xf…

iclone acculips Visemes (Adding Visemes to Dictionary)

(New for v7.9) 将视位添加到词典&#xff08;v7.9 的新增功能&#xff09; AccuLips has a dictionary behind the scenes to map and convert voice to text. Needless to say, some existing English lexicon can still be missing from the dictionary, and cause the cor…

java BioJava库安装和使用

BioJava是一个用Java编写的开源生物信息学库&#xff0c;旨在为生物学家和生物信息学家提供工具和算法来处理生物数据。它提供了一系列功能强大的工具&#xff0c;包括读取、写入和解析常见的生物信息学文件格式&#xff08;如FASTA、GenBank等&#xff09;&#xff0c;进行序列…