springCloud之OAuth2

news2024/10/6 6:04:07

认证授权过程

在认证和授权的过程中涉及的三方包括:

1、服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。

2、用户,存放在服务提供方的受保护的资源的拥有者。

3、客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。

使用OAuth进行认证和授权的过程如下所示:

用户想操作存放在服务提供方的资源。

用户登录客户端向服务提供方请求一个临时令牌。

服务提供方验证客户端的身份后,授予一个临时令牌。

客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方。

用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。

授权成功后,服务提供方引导用户返回客户端的网页。

客户端根据临时令牌从服务提供方那里获取访问令牌。

服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。

客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。

一、服务端搭建

项目结构

1、依赖

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

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

        <!--  OAuth2.0依赖,不再内置了,所以得我们自己指定一下版本  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

2、配置文件

package com.minos.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

import javax.annotation.Resource;

@EnableAuthorizationServer   //开启验证服务器
@Configuration
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

    @Resource
    private AuthenticationManager manager;
    @Resource
    UserDetailsService service;


    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    /**
     * 这个方法是对客户端进行配置,一个验证服务器可以预设很多个客户端,
     * 之后这些指定的客户端就可以按照下面指定的方式进行验证
     * @param clients 客户端配置工具
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .inMemory()   //这里我们直接硬编码创建,当然也可以像Security那样自定义或是使用JDBC从数据库读取
                .withClient("web")   //客户端名称,随便起就行
                .secret(encoder.encode("654321"))      //只与客户端分享的secret,随便写,但是注意要加密
                .autoApprove(false)    //自动审批,这里关闭,要的就是一会体验那种感觉
                .scopes("book", "user", "borrow")     //授权范围,这里我们使用全部all
                .redirectUris("http://localhost:8201/login")   //可以写多个,当有多个时需要在验证请求中指定使用哪个地址进行回调
                .authorizedGrantTypes("client_credentials", "password", "implicit", "authorization_code", "refresh_token");
        //授权模式,一共支持5种,除了之前我们介绍的四种之外,还有一个刷新Token的模式
        //这里我们直接把五种都写上,方便一会实验,当然各位也可以单独只写一种一个一个进行测试
        //现在我们指定的客户端就支持这五种类型的授权方式了
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security
                .passwordEncoder(encoder)    //编码器设定为BCryptPasswordEncoder
                .allowFormAuthenticationForClients()  //允许客户端使用表单验证,一会我们POST请求中会携带表单信息
                .checkTokenAccess("permitAll()");     //允许所有的Token查询请求
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .authenticationManager(manager);
        //由于SpringSecurity新版本的一些底层改动,这里需要配置一下authenticationManager,才能正常使用password模式
        endpoints
                .userDetailsService(service);
    }
}
package com.minos.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()  //
                .and()
                .formLogin().permitAll();    //使用表单登录
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        auth
                .inMemoryAuthentication()   //直接创建一个用户,懒得搞数据库了
                .passwordEncoder(encoder)
                .withUser("test").password(encoder.encode("123456")).roles("USER");
    }

    @Bean   //这里需要将AuthenticationManager注册为Bean,在OAuth配置中使用
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

3、配置属性

server:
  port: 8500
  servlet:
    #为了防止一会在服务之间跳转导致Cookie打架(因为所有服务地址都是localhost,都会存JSESSIONID)
    #这里修改一下context-path,这样保存的Cookie会使用指定的路径,就不会和其他服务打架了
    #但是注意之后的请求都得在最前面加上这个路径
    context-path: /sso

二、服务端测试

1、客户端模式

http://localhost:8500/sso/oauth/token
grant_type:client_credentials
client_id:web
client_secret:654321

验证token

http://localhost:8500/sso/oauth/check_token?token=7cd6c753-bd1f-4a41-aa60-372dc43f2a70

 

2、密码模式

http://localhost:8500/sso/oauth/token
grant_type:password
username:test
password:123456

 填写请求参数

 设置校验账号密码

 3、隐式授权模式

浏览器调用

http://localhost:8500/sso/oauth/authorize?client_id=web&response_type=token

 服务器根据规则携带token重定向至http://localhost:8201/login

http://localhost:8201/login#access_token=2d81d2ff-898f-4138-bc0b-a46c2c15a13c&token_type=bearer&expires_in=42373&scope=book%20borrow%20user

 4、授权码模式

http://localhost:8500/sso/oauth/authorize?client_id=web&response_type=code

 浏览器页面登录

 

 勾选权限

 

 返回code

http://localhost:8201/login?code=4om04n

 根据返回code获取token

http://localhost:8500/sso/oauth/token
grant_type:authorization_code
client_id:web
client_secret:654321
code:4om04n

 5、刷新token

http://localhost:8500/sso/oauth/token
grant_type:refresh_token
client_id:web
client_secret:654321
refresh_token:b1eda2a0-d1bd-4bd3-9c48-67115e159bf2

三、基于@EnableOAuth2Sso实现自动登录

1、导入依赖

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

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

2、启动类添加开启注解

@EnableOAuth2Sso

 3、配置文件增加配置

security:
  oauth2:
    client:
      #不多说了
      client-id: web
      client-secret: 654321
      #Token获取地址
      access-token-uri: http://localhost:8500/sso/oauth/token
      #验证页面地址
      user-authorization-uri: http://localhost:8500/sso/oauth/authorize
    resource:
      #Token信息获取和校验地址
      token-info-uri: http://localhost:8500/sso/oauth/check_token

四、基于@EnableResourceServer实现资源服务器

 1、导入依赖

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

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

2、启动类添加开启注解

@EnableResourceServer

 3、配置文件增加配置

security:
  oauth2:
    client:
      #不多说了
      client-id: web
      client-secret: 654321
      #Token获取地址
      access-token-uri: http://localhost:8500/sso/oauth/token
      #验证页面地址
      user-authorization-uri: http://localhost:8500/sso/oauth/authorize
    resource:
      #Token信息获取和校验地址
      token-info-uri: http://localhost:8500/sso/oauth/check_token

4、权限范围校验

@Configuration
public class ResourceConfiguration extends ResourceServerConfigurerAdapter { //继承此类进行高度自定义

    @Override
    public void configure(HttpSecurity http) throws Exception {  //这里也有HttpSecurity对象,方便我们配置SpringSecurity
        http
                .authorizeRequests()
                .anyRequest().access("#oauth2.hasScope('lbwnb')");  //添加自定义规则
      					//Token必须要有我们自定义scope授权才可以访问此资源
    }
}

5、RestTemplate 远程调用携带token

@Configuration
public class WebConfiguration {

    @Resource
    OAuth2ClientContext context;

    @Bean
    public OAuth2RestTemplate restTemplate(){
        return new OAuth2RestTemplate(new ClientCredentialsResourceDetails(), context);
    }
}

 使用OAuth2RestTemplate进行调用,自动携带token

  @Resource
    OAuth2RestTemplate template;

6、Feign调用携带token

OpenFeign使用参考。

https://blog.csdn.net/qq_29752857/article/details/129221077
feign:
  oauth2:
  	#开启Oauth支持,这样就会在请求头中携带Token了
    enabled: true
    #同时开启负载均衡支持
    load-balanced: true

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

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

相关文章

【spring】事务

概述 1、什么事务 事务是数据库操作最基本单元&#xff0c;逻辑上一组操作&#xff0c;要么都成功&#xff0c;如果有一个失败所有操 作都失败 2、事务四个特性&#xff08;ACID&#xff09; &#xff08;1&#xff09;原子性 &#xff08;2&#xff09;一致性 &#xff08;3…

java语言跨平台的特性:“一次编译,到处运行”

“一次编译&#xff0c;到处运行”是java语言跨平台的特性&#xff0c;平台指的是操作系统平台。 程序从源代码到运行的三个必经阶段&#xff1a;编码——编译——运行&#xff0c;调试。 首先编码阶段&#xff0c;需要编码语言是一个程序设计语言&#xff0c;而我们的java是程…

ChatGPT解答:python大批量读写ini文件时,性能很低,有什么解决方法吗,给出具体的思路和实例

ChatGPT解答&#xff1a; python大批量读写ini文件时&#xff0c;性能很低&#xff0c;有什么解决方法吗&#xff0c;给出具体的思路和实例 ChatGPTDemo Based on OpenAI API (gpt-3.5-turbo). python大批量读写ini文件时&#xff0c;性能很低&#xff0c;有什么解决方法吗&…

springboot工程搭建的几种方式

一、通过idea工具搭建&#xff0c;如下&#xff1a; 新建Project和Module&#xff0c;选择Spring initializr&#xff0c;点击Next&#xff0c;进入到如下页面填写 填写完后点击Next 到如下页面&#xff0c;根据你的具体所需&#xff0c;选择要使用的技术依赖 点击Next 点击FIn…

巾帼绽芬芳 一起向未来(中篇)

编者按&#xff1a;为了隆重纪念纪念“三八”国际妇女节113周年&#xff0c;快来与你全方位、多层次分享交流“三八”国际妇女节的前世今生。分上篇&#xff08;节日简介、节日发展和节日意义&#xff09;、中篇&#xff08;节日活动宗旨和世界各国庆祝方式&#xff09;和下篇&…

云原生之docker网络详解

云原生之docker网络详解一、相关概念1.2、CNM1.3、libnetwork二、实操2.1、docker network常用命令2.2、运行一个docker容器&#xff0c;查看CNM三个概念2.3、查看docker0在内核路由表上的记录2.4、查看网络列表2.5、网络隔离效果展示2.6、host驱动网络一、相关概念 1.1、网桥…

链表经典刷题--快慢指针与双指针

本篇总结链表解题思路----快慢指针&#xff0c;其实也就是双指针&#xff0c;这个快慢并不单纯指“快慢”&#xff0c;它更多的可以表示&#xff0c;速度快慢&#xff0c;距离长度&#xff0c;时间大小等等&#xff0c;用法很有趣也很独特&#xff0c;理解它的思想&#xff0c;…

「并发编程实战」常见的限流方案

「并发编程实战」常见的限流方案 文章目录「并发编程实战」常见的限流方案一、概述二、计数器限流方案三、时间窗口限流方案四、令牌桶限流方案五、漏桶限流方案六、高并发限流算法小结文章参考&#xff1a; 追忆四年前&#xff1a;一段关于我被外企CTO用登录注册吊打的不堪往事…

01 | n2n虚拟局域网

1 n2n简介 为了满足两个不同局域网的机器进行通信&#xff0c;让不同网段的机器能够进行P2P( 点对点 peer-to-peer ) 通信。2 n2n源码 https://github.com/ntop/n2n.git3 n2n名词 3.1 SuperNode 超级节点 SuperNode 相当与注册中心, 它会记录边缘节点的连接信息&#xff0c;…

案例09-数据类型不一致导致equals判断为false

一&#xff1a;背景介绍 在判断课程id和班级id的时候如果一致就像课程信息进行更新&#xff0c;如果不一致就插入一条新的数据。其实两个变量的值是一致的但是类型是不一致的。这就导致数据库中已经有一条这样的数据了&#xff0c;在判断的时候结果为false&#xff0c;就有插入…

【这一篇就够】mysql创建JSON数据的索引

一. 创建索引 由于json有两类不同的数据形式&#xff0c;即&#xff1a;json对象&#xff08;如&#xff1a;{"id": 1, "name":"he"}&#xff09;&#xff0c;json数组&#xff08;如&#xff1a;["1","2","3"]&…

nexus安装与入门

安装 nexus-3.31.1-01-unix.tar.gz 链接&#xff1a;https://pan.baidu.com/s/1YrJMwpGxmu8N2d7XMl6fSg 提取码&#xff1a;kfeh 上传到服务器&#xff0c;解压 tar -zvxf nexus-3.31.1-01-unix.tar.gz进入bin目录&#xff0c;启动 ./nexus start查看状态 ./nexus status默…

初始Linux操作系统

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。座右铭&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石&#xff0c;故能成其高。个人主页&#xff1a;小李会科技的…

Linux常用命令等

目录 1.Linux常用命令 (1)系统命令 (2)文件操作命令 2.vim编辑器 3.linux系统中,软件安装 (1) rpm 安装,RedHat Package Manager (2)yum 安装 (3)源代码编译安装 1.Linux常用命令 Linux命令是非常多的,对于像嵌入式开发工程师,运维工程师需要掌握的命令是非常多的.对于…

旋转矩形框标注--roLabelImg的使用

1. 旋转目标标注roLabelImg roLabelImg是一款开源的,可标注带旋转角度的矩形区域的标注软件。roLabelImg源码github地址: https://github.com/cgvict/roLabelImg labelme和labelimg只能标矩形框,但不能标注旋转角度。roLabelImg既能标矩形框也能标注矩形框的选择角度,因此…

复旦发布中国版 ChatGPT :MOSS

不知道这个人工智能&#xff0c;有没有获得完整的一生。ChatGPT 是最先进的 AI&#xff0c;也是最热门的应用 —— 自去年 11 月底发布以来&#xff0c;它的月活跃用户两个月超过一亿&#xff0c;轻松拿到了全球互联网史上用户增长速度的第一。它也是一种门槛很高的技术。由于 …

服务预热配置化在泛型化方法上的实践

背景 由于开发过程中&#xff0c;个别dubbo接口的调用会在服务发布过程中&#xff0c;出现P99耗时报警问题。因此我们计划通过预热服务接口&#xff0c;通过预热来触发JIT&#xff0c;构建DB资源长链接。实现服务接口上线后&#xff0c;耗时过长&#xff0c;资源等待等问题&am…

基于RWEQ模型的土壤风蚀模数估算及其变化归因分析

查看原文>>>基于RWEQ模型的土壤风蚀模数估算及其变化归因分析 土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一&#xff0c;土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。中国风蚀荒漠化面积达160.74104km2&#xff…

python re模块匹配字符串

python 正则模块re 要使用python3中的RE则必须引入 re模块 import re re模块的match函数 result re.match(^[A-Z]{1}[a-z], s) match 尝试从字符串的起始位置匹配一个模式&#xff0c;如果不是起始位置匹配成功的话&#xff0c;match()就返回none。 匹配到了&#xff0c;则…

AI for Science系列(二):国内首个基于AI框架的CFD工具组件!赛桨v1.0 Beta API介绍以及典型案例分享!

AI for Science被广泛认为是下一代科研范式&#xff0c;可以有效处理多维度、多模态、多场景下的模拟和真实数据&#xff0c;解决复杂推演计算问题&#xff0c;加速新科学问题发现[1] 。百度飞桨科学计算工具组件赛桨PaddleScience是国内首个公开且可应用于CFD&#xff08;Comp…