Spring Security整合Gitee第三方登录

文章目录

  • 学习链接
  • 环境准备
    • 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 {@Overrideprotected void configure(HttpSecurity http) throws Exception {/* 配置表单登录 *//* 1. 如果不添加上表单登录, 那么直接访问:localhost:9090 会显示403的白页, 这是因为ExceptionTranslationFilter此时用的authenticationEntryPoint的类型是: Http403ForbiddenEntryPoint2. 如果添加上表单登录, 那么直接访问: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();}@Beanpublic PasswordEncoder passwordEncoder() {HashMap<String, PasswordEncoder> encoders = new HashMap<>();encoders.put("bcrypt", new BCryptPasswordEncoder());return new DelegatingPasswordEncoder("bcrypt", encoders);}@Beanpublic 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 {@Autowiredprivate GiteeClient giteeClient;@Overrideprotected 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());}@Beanpublic PasswordEncoder passwordEncoder() {HashMap<String, PasswordEncoder> encoders = new HashMap<>();encoders.put("bcrypt", new BCryptPasswordEncoder());return new DelegatingPasswordEncoder("bcrypt", encoders);}@Beanpublic 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_IDclient-secret: YOUR_SECRETauthorization-grant-type: authorization_coderedirect-uri: '{baseUrl}/{action}/oauth2/code/{registrationId}'client-name: giteeprovider: giteescope:- user_infoprovider:gitee:authorization-uri: https://gitee.com/oauth/authorizetoken-uri: https://gitee.com/oauth/tokenuser-info-uri: https://gitee.com/api/v5/useruser-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 {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.oauth2Login();http.formLogin();http.authorizeRequests().anyRequest().authenticated();}@Beanpublic PasswordEncoder passwordEncoder() {HashMap<String, PasswordEncoder> encoders = new HashMap<>();encoders.put("bcrypt", new BCryptPasswordEncoder());return new DelegatingPasswordEncoder("bcrypt", encoders);}@Beanpublic UserDetailsService userDetailsService() {return username -> {if ("zzhua".equals(username)) {return new User("zzhua", passwordEncoder().encode("zzhua"), AuthorityUtils.createAuthorityList("admin"));}return null;};}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SheetJS V0.17.5 导入 Excel 异常修复 Invalid HTML:could not find<table>

导入 Excel 提示错误&#xff1a;Invalid HTML:could not find<table> 检查源代码 发现 table 属性有回车符 Overview: https://docs.sheetjs.com/docs/ Source: https://git.sheetjs.com/sheetjs/sheetjs/issues The public-facing websites of SheetJS: sheetjs.com…

postman教程-7-文件上传接口

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了postman发送get请求的方法&#xff0c;本小节我们讲解一下postman文件上传接口的请求方法。 postman文件上传的方式大概有两种&#xff0c;一种是form-data类型上传文件&#xff0c;一种是bin…

redis数据类型之Hash,Bitmaps

华子目录 Hash结构图相关命令hexists key fieldhmset key field1 value1 [field2 value2...]hscan key cursor [MATCH pattern] [COUNT count] Bitmaps位图相关命令setbit1. **命令描述**2. **语法**3. **参数限制**4. **内存分配与性能**5. **应用实例**6. **其他相关命令**7.…

stm32学习-CubeIDE使用技巧

1.hex文件生成 右键工程 2.仿真调试 3.常用快捷键 作用快捷键代码提示alt/代码注释/反注释ctrl/ 4.项目复制 复制项目&#xff0c;将ioc文件名改为项目名即可图形化编辑

元宇宙三维互动展厅让体验者进入一个充满奇幻与创意的数字世界

元宇宙数字产品展厅搭建编辑器凭借强大的三维可视化互动功能&#xff0c;为用户带来前所未有的沉浸式数字展览体验。 在元宇宙数字产品展厅搭建编辑器中&#xff0c;用户可以轻松打造逼真的三维展览环境&#xff0c;通过VR虚拟现实技术&#xff0c;仿佛置身于一个充满奇幻与创意…

爬虫案例(读书网)

一.我们还是使用简单的bs4库和lxml&#xff0c;使用xpath&#xff1a; 导入下面的库&#xff1a; import requests from bs4 import BeautifulSoup from lxml import etree 我们可以看见它的div和每个书的div框架&#xff0c;这样会观察会快速提高我们的简单爬取能力。 二.实…

LabVIEW机器设备的振动监测

振动监测是工业和机械维护中重要的一部分&#xff0c;通过检测和分析机械振动&#xff0c;提前发现潜在故障&#xff0c;确保设备的可靠运行。LabVIEW是一种强大的图形化编程环境&#xff0c;非常适合用于振动监测系统的开发和实施。以下从多个角度详细介绍LabVIEW在振动监测中…

拷贝构造、移动构造、拷贝赋值、移动赋值

最近在学习C的拷贝构造函数时发现一个问题&#xff1a;在函数中返回局部的类对象时&#xff0c;并没有调用拷贝构造函数。针对这个问题&#xff0c;查阅了一些资料&#xff0c;这里记录整理一下。 调用拷贝构造函数的三种情况&#xff1a; ① 用一个类去初始化另一个对象时&a…

重学java 51.Collections集合工具类、泛型

"我已不在地坛&#xff0c;地坛在我" —— 《想念地坛》 24.5.28 一、Collections集合工具类 1.概述:集合工具类 2.特点: a.构造私有 b.方法都是静态的 3.使用:类名直接调用 4.方法: static <T> boolean addAll(collection<? super T>c,T... el…

民国漫画杂志《时代漫画》第17期.PDF

时代漫画17.PDF: https://url03.ctfile.com/f/1779803-1248612629-85326d?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

LVM、磁盘配额

LVM与磁盘配额 一、LVM LVM(逻辑卷管理)&#xff1a;是Linux系统下对硬盘分区的管理机制。 LVM机制适合于管理管理大存储设备。可以动态对硬盘进行扩容。 逻辑上的磁盘&#xff0c;概念上的磁盘&#xff0c;文件系统创建之后不考虑底层的物理磁盘。 若干个磁盘分区或者物理…

与MySQL的初相遇

&#x1f30e;初识MySQL 注&#xff1a;本文SQL语句只为了验证猜想&#xff0c;不会也不要紧。 文章目录&#xff1a; MySql开端 认识数据库       什么是数据库       主流数据库       MySQL的本质 MySQL基础使用       连接mysql服务器     …

【Linux 网络编程】协议的分层知识!

文章目录 1. 计算机网络背景2. 认识 "协议"3. 协议分层 1. 计算机网络背景 网络互联: 多台计算机连接在一起, 完成数据共享; &#x1f34e;局域网&#xff08;LAN----Local Area Network&#xff09;: 计算机数量更多了, 通过交换机和路由器连接。 &#x1f34e; 广…

CTFHUB技能树——SSRF(三)

目录 URL Bypass 数字IP Bypass 302跳转 Bypass DNS重绑定 Bypass SSRF绕过方法&#xff1a; &#xff08;1&#xff09; http://abc.com127.0.0.1 &#xff08;2&#xff09;添加端口号 http://127.0.0.1:8080 &#xff08;3&#xff09;短地址 htt…

HTTP Digest Access Authentication Schema

HTTP Digest Access Authentication Schema 背景介绍ChallengeResponse摘要计算流程总结参考 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 HTTP Digest Access Authentication Schema&#xff…

Android 控件保持宽高比得几种方式

文章目录 Android 控件保持宽高比得几种方式adjustViewBounds百分比布局ConstraintLayout自定义View Android 控件保持宽高比得几种方式 adjustViewBounds 仅适用于 ImageView&#xff0c;保持横竖比。 <ImageViewandroid:layout_width"match_parent"android:l…

STL-priority_queue的使用及其模拟实现

优先级队列(priority_queue)默认使用vector作为其底层存储数据的容器&#xff0c;在vector上又使用了堆算法将vector中的元素构造成堆的结构&#xff0c;因此priority_queue就是堆&#xff0c;所有需要用到堆的位置&#xff0c;都可以考虑使用priority_queue。 注意&#xff1…

车载电子电器架构 —— 智能座舱标准化意义

车载电子电器架构 —— 智能座舱标准化意义 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…

Python 之微信指数小程序数据抓取

Fiddler安装和设置 安装 Fiddler 安装包可以从这里获取&#xff0c;如果失效了可以自己网上找一个安装。 链接&#xff1a;https://pan.baidu.com/s/10tYQ-uL6HMddkOcIKnWEKQ?pwdd1io 然后就是点击安装就好了&#xff0c;没什么好多说的。 启用HTTPS捕获 进入软件界面&…

数据库设计实例---学习数据库最重要的应用之一

一、引言【可忽略】 在学习“数据库系统概述”这门课程时&#xff0c;我一直很好奇&#xff0c;这样一门必修课&#xff0c;究竟教会了我什么呢&#xff1f; 由于下课后&#xff0c;&#xff0c;没有拓展自己的眼界&#xff0c;上课时又局限于课堂上老师的讲课水平&#xff0c;…