spring security oauth2学习 -- 快速入门

news2024/10/7 2:27:14

 1.Oauth2认证协议

简单理解:

OAuth2是目前最流行的授权协议,用来授权第三方应用,获取用户数据。

 1.1 流程

 客户端通过认证和授权,向资源服务器去访问资源。

其中,授权和认证都需要在授权服务器,由资源拥有者(这里不指客户端),授予访问权限

1.2 token

 授权码:是用于向授权服务器申请访问令牌的一种凭据,客户端通过向授权服务器发送请求获取授权码,随后再使用该授权码向授权服务器请求访问令牌,从而获取对资源的访问权限

1.3 会话技术

一般是指cookie和session之间建立的一种会话机制。

1.假如我们登录,访问CSDN,就是跟服务器长久建立一次会话技术。通过CSDN服务器生成的session id,通过cookie响应到客户端。

2.当我访问服务器其他资源时,我客户端中的cookie中的session id 与服务器储存着的session id 进行比对。

3.找到相应的,返回给我们和上次请求相同的数据。

作用:判别是否是同一浏览器的http请求。

 2.SpringSecurityOauth2架构模式

对下面图流程(图起参考作用)就是:

  1. 我访问资源服务器,要经过Client因为没有token,Oauth2RestTemplate会报错,被Oauth2RestFiter捕获。
  2. 重定向到 Authoraization server(授权服务器),经过Authorization Endpoint(授权端点),再到AuthorizationServerTokenServices,获得授权码.
  3. 我们拿到授权码后,还是要经过TokenEndPoint(令牌端点),再到AuthorizationServerTokenServices,获得token
  4. 客户端有了token后,拿着token访问资源通过Oauth2AuthenticationManager调用ResourceServerTokenServices进行校验

2.1 授权模式

包目录

2.1.1 导入依赖

		<!--版本号-->
        <spring-boot.version>2.6.13</spring-boot.version>
		<spring-cloud.version>2021.0.7</spring-cloud.version>

	<!--lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<!--oauth2-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-oauth2</artifactId>
			<version>2.2.2.RELEASE</version>
		</dependency>
		<!--security-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-security</artifactId>
			<version>2.2.2.RELEASE</version>
		</dependency>

	<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>
         <!--spring-cloud依赖-->
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

2.1.2 流程大概

1.我们不是自定义实现UserDetailService 去自定义 loadUserByUsername()方法,

2.自定义SercutiyConfig extends WebSecurityConfigurerAdapter 继承这个逻辑。

3.自定义 AuthenticationServer extends AuthorizationServerConfigurerAdapter (在实际开发中,授权服务器逻辑是框架帮我们定义的)

4. 自定义 ResourcesServerConfig extends ResourceServerConfigurerAdapter(也就是我们没用框架时候的资源)

2.1.3 代码实现

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


        //@Override
        //protected void configure(AuthenticationManagerBuilder auth) throws Exception {    //auth.inMemoryAuthentication()
        //    auth.inMemoryAuthentication()
        //            .withUser("lxs")
        //            .password("{noop}123") //使用springsecurity5,需要加上{noop}指定使用NoOpPasswordEncoder给DelegatingPasswordEncoder去校验密码
        //            .roles("admin");
        //}


        @Override
        //解决静态资源被拦截的问题
        public void configure(WebSecurity web) throws Exception {

         // web.ignoring().antMatchers("/asserts/**");
        }


        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    // 所有符合下面路径,放行
                    .antMatchers("/oauth/**","/login/**","/logout/**").permitAll()
                    // 剩下任何请求,都要认证后才能访问。
                    .anyRequest().authenticated()
                    .and().formLogin().permitAll()
                    // 关闭跨域保护;
                    .and().csrf().disable();
        }


        // 密码容器
        @Bean
        public PasswordEncoder passwordEncoder(){
                return new BCryptPasswordEncoder();
        }

    }

 AuthenticationServer.java(授权服务器,实际情况由框架定义)

@Configuration
@EnableAuthorizationServer
public class AuthenticationServer extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                // id 和 secret 也是oauth处理的
                .withClient("admin") // 配置 client - id
                .secret(passwordEncoder.encode("112233")) // 配置client- secret 简单理解秘钥
                .accessTokenValiditySeconds(3600)// 配置access-token有效时间
                .redirectUris("http://www.baidu.com")// 配置配置拿到令牌后重定向的网址(客户端)
                .scopes("all")// 配置申请的权限范围
                .authorizedGrantTypes("authorization_code"); // 配置授权类型
    }
}

 ResourcesServerConfig.java

@Configuration
@EnableResourceServer
public class ResourcesServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                // 参考一下securityConf中对资源的拦截
                .and().requestMatchers().antMatchers("/user/**");
    }
}

UserController.java 

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/getCurrentUser")
    public Object getCurrentUser(Authentication authentication){
        Object principal = authentication.getPrincipal();
        return principal;

    }
}

1.访问地址 ,先去授权服务器的 授权端点,拿授权码。路径参数,都是授权服务器的配置。

http://localhost:8888/oauth/authorize?response_type=code&client_id=admin&redirect_uri=http://www.baidu.com&scope=all

2.点击approve ,再点击 Authorize

  3.跳转到网址,这里有授权码

.

 4.之后再去令牌端点,拿token。

http://localhost:8888/oauth/token

PostMan配置

 这里要和你 授权服务器的配置 对应

PS: 一旦你请求失败,需要重新获取授权码

 5.拿到token后,就能访问资源服务器了

{
    "access_token": "t-nFqHHJWc3cFzD4q0p4RF8a--Y", // 令牌码
    "token_type": "bearer", // 令牌类型
    "expires_in": 3599, // 有效期
    "scope": "all" // 访问范围
}

 6.成功拿到请求数据

2.2 密码模式

利用上述demo授权码模式 demo的基础上修改。

说白了,我就绕过授权码,用登录的用户名和密码直接拿token。token -> 资源服务器

之前是 授权码 -> token -> 资源服务器

 AuthenticationServer.java

 @Autowired
    private UserService userService; // ----新增

    @Autowired
    private AuthenticationManager authenticationManager; // ----新增

    /**
     *  密码模式
     * @param
     * @return
     */
    @Override  // -----新增
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                // id 和 secret 也是oauth处理的
                .withClient("admin") // 配置 client - id
                .secret(passwordEncoder.encode("112233")) // 配置client- secret 简单理解秘钥
                .accessTokenValiditySeconds(3600)// 配置access-token有效时间
                .redirectUris("http://www.baidu.com")// 配置配置拿到令牌后重定向的网址(客户端)
                .scopes("all")// 配置申请的权限范围
                .authorizedGrantTypes("password"); // 配置授权类型  // ------修改
        // authorization_code
    }

SecurityConfi.java

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
                return super.authenticationManagerBean();
        }

 2.3 redis存储token

2.3.1 导入相关依赖

	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<!--commons-pools连接池,lettuce没有内置的数据库连接池所以要用第三方的 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>

 2.3.2 yml配置文件

# redis配置
spring:
  redis:
    password: 123456
    # 默认0库
    database: 0
    #连接超时时间
    timeout: 10000ms
    port: 6379
    host: 192.168.88.135
    lettuce:
      pool:
        # 设置最大连接数
        max-active: 1024
        # 最大阻塞时间
        max-wait: 10000ms
        # 最大空间连接,默认8
        max-idle: 200
        # 最小空间连接,默认5
        min-idle: 5

 RedisConfig.java 

新建RedisConfig,你可以理解为我们新建redis

@Configuration
public class RedisConfig {


    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    // 这好像是security-oauth2 专门用来新增redis用的
    public TokenStore redisTokenStore(){
        return new RedisTokenStore(redisConnectionFactory);
    }
}

 AuthenticationServer.java  新加配置

 @Autowired
    @Qualifier("redisTokenStore")
    private RedisTokenStore redisTokenStore; // ----新增
    /**
     *  密码模式
     * @param
     * @return
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService)
                .tokenStore(redisTokenStore); // ----新增 
    }

 会发现你的数据库里面新增5个token。

 

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

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

相关文章

【Java】parallelStream().forEach() 的踩坑日记

文章目录 前言踩坑日记刨根问底解决方案小结 前言 最近一直在开发项目中的新需求&#xff0c;其中有一个需求是“解析文件&#xff08;.txt文件&#xff0c;一行就是一条数据&#xff09;中的数据并进行入库操作”。其实这个需求也很简单&#xff0c;无非就是将文件中每一行数…

架构师必须掌握的架构设计原则

如果一个架构或设计原则已经存在 15 年&#xff0c;例如单一职责和依赖倒置原则&#xff0c;我可以预期它还有 15 年甚至更久的生命期。原则是比具体技术更抽象&#xff0c;更接近事物本质&#xff0c;也更经得起时间考验的东西。这些原则沉淀在架构师的脑海中&#xff0c;最终…

彻底理解 linux 的内存回收

本文试图用最浅显的语言说明以下问题&#xff1a; 1、free 命令中的buffer/cache 是什么意思&#xff1f; 2、内存回收的机制是什么&#xff1f; 3、内存回收的门限是什么&#xff1f;也就是什么时候进行回收&#xff1f; 4、如何手动清除cache&#xff1f; 1、free 命令中的bu…

【高危】Apache NiFi H2驱动存在代码注入漏洞

漏洞描述 Apache NiFi 是一个开源的数据流处理和自动化工具&#xff0c;DBCPConnectionPool 和 HikariCPConnectionPool 是两个控制器服务&#xff0c;用于提供对数据库的连接池管理功能。 Apache NiFi 受影响版本&#xff0c;由于 DBCPConnectionPool 和 HikariCPConnectio…

景点景区门票购买核销宴会活动报名公众号系统开发

景点景区门票购买核销宴会活动报名公众号系统开发 功能特性 1.活动管理 可以新建一场或多场活动&#xff0c;管理每一场活动&#xff1b;与此同时&#xff0c;可以添加多张收费或免费门票&#xff0c;满足特定的需求&#xff1b;填写举办城市后&#xff0c;客户可通过定位服务&…

Vue + Axios全局接口防抖、节流封装实现,让你前端开发更高效

你是否有过这样的经历&#xff0c;每当你在前端开发中使用 Ajax 进行数据请求时&#xff0c;往往因为一些错误操作导致页面不断地发送请求&#xff0c;甚至导致了系统崩溃&#xff1f;为了解决这个问题&#xff0c;我们需要对接口进行防抖和节流处理。 本文将介绍如何使用 Vue …

Windows BAT脚本指令总结和笔记

最近在工作的项目工程中遇到了各式各样的bat脚本&#xff0c;故总结和记录下所遇到的指令&#xff1b; 文章目录 1 echo off2 REF3 SET4 %~dp05 %~nx06 CALL7 pushd8 rmdir 1 echo off echo off的意思是在批处理运行命令的时候不会一条一条的显示执行的命令&#xff0c;与之相…

香港Web3欲戴王冠,银行如何承受合规之重?

前言 6月19日&#xff0c;据明报报道&#xff0c;香港金融管理局&#xff08;HKMA&#xff09;总裁余伟文针对虚拟资产交易平台在香港银行开户难问题表示&#xff0c;一向有与香港银行有交流&#xff0c;“交流时是否有压力则大家感觉不一”。上周四&#xff0c;HKMA向汇丰银行…

vulhub-struts2-S2-005 远程代码执行漏洞复现

漏洞描述 s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12)&#xff0c;struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象&#xff0c;struts框架通过过滤#字符防止安全问题&#xff0c;然而通过unicode编码(…

优维低代码实践:面包屑配置以及菜单配置

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

Pyinstaller打包Sklearn(即scikit-learn)+Pyqt5代码报错,程序无法正常运行

前言 在网上看了大部分解决办法都不能解决我的问题&#xff0c;后面自己摸索之后&#xff0c;解决问题&#xff0c;记录如下。 提供一篇大佬文章&#xff0c;一般能解决大部分问题&#xff1a; https://blog.csdn.net/u012219045/article/details/115397646 建议先看我的文章…

Java复习0619

关键字: static Static&#xff1a;静态的&#xff0c;随着类的加载而加载、执行。static用来修饰: 属性、方法、代码块、内部类熟悉: static修饰的类变量、类方法与不使用static修饰的区别。 类变量: 类的生命周期内&#xff0c;只有一个。被类的多个实例共享。 掌握: 我们遇…

企业备份和恢复软件推荐

数据备份是在发生灾难或事故时通过将数据从一个位置复制到另一个位置来保护数据的过程。数据是任何组织的生命线&#xff0c;丢失数据会导致严重损坏并中断业务运营。96% 的用户至少经历过数据丢失的主要原因之一&#xff1a;人为错误、硬盘驱动器故障、断电、火灾和自然灾害。…

ES(Elasticsearch)和Kibana(Windows)安装

安装Elasticsearch和Kibana 安装Elasticsearch过程 首先需要到官网下载安装包 注意&#xff1a;要下载对应的版本&#xff0c;如果下载最新版而且jdk是1.8版本的话&#xff0c;会出现warning: ignoring JAVA_HOMEC:\Program Files\Java\jdk1.8.0_191; using bundled JDK这样…

Git本地仓库使用

说明&#xff1a;Git是版本控制和协同开发的工具 下载Git 第一步&#xff1a;下载 在官网&#xff08;https://git-scm.com/download/win&#xff09;&#xff0c;选择自己的版本自行下载 第二步&#xff1a;安装 下载下来后&#xff0c;使用默认设置&#xff0c;不要改动任…

Redis6之配置文件与发布订阅

配置文件 ################################### NETWORK ############################## # 指定 redis 只接收来自于该IP地址的请求&#xff0c;如果不进行设置&#xff0c;那么将处理所有请求 bind 127.0.0.1#是否开启保护模式&#xff0c;默认开启。要是配置里没有指定b…

Java和bean(VO)、dao、Servlet、jsp的综合总结复习

学到这里&#xff0c;差不多&#xff0c;可以自主完成一个简单的系统了。所以接下来需要总结&#xff0c;然后设计一个简单的系统。分别使用Java和Java Web来实现。&#xff08;目标&#xff1a;实现简单的购物系统&#xff09; 要求&#xff1a;能注册&#xff0c;并登录。登…

【python】四舍五入保留N位小数,截断保留小数

目录 一.环境 二.适用场景 三.具体方法代码及描述 1.方法一&#xff1a;numpy-around()方法&#xff0c;四舍五入 2.方法二&#xff1a;字符串格式化&#xff08;有两种方式&#xff0c;均为四舍五入&#xff09;【推荐】 1&#xff09;%.4f 法 2) {:.4f} 法 3.方法三…

QT入门基础知识

什么是QT QT是一个跨平台的C图像用户界面应用程序框架QT在1991年由奇趣科技开发QT的优点 跨平台,几乎支持所有平台接口简单&#xff0c;容易上手一定程度上简化了内存回收机制有很好的社区氛围可以进行嵌入式开发 QWidget QT注意事项 命名规范 类名 首字母大写&#xff0c;单…

kakfa 常见错误(长期更新)

kafka版本 2.13-3.40 一、消费者相关1.1 消费组1.1.1 查看消费组命令找不到消费组 1.2 主题1.2.1 kafka默认主题_consumer_offsets 不小心删除 二、发布者相关三、Spring Boot连接相关3.1 消费者相关3.1.1 连接报错3.1.1.2 消费报错 一、消费者相关 1.1 消费组 1.1.1 查看消费…