OAuth2.0客户端和服务端Java实现

oauth2

引言

读了《设计模式之美》和《凤凰架构》架构安全篇之后,决定写一个OAuth2.0的认证流程的Demo,也算是一个阶段性的总结,具体原理实现见《凤凰架构》(架构安全设计篇)。

涉及到的源码可以从https://github.com/WeiXiao-Hyy/oauth2获取,欢迎Star!

OAuth2.0原理

主要解决的问题

面向解决第三方应用(Third-Party Application)的认证授权协议,使用Token代替用户密码作为授权的凭证。

  1. 有了令牌之后,哪怕令牌被泄漏,也不会导致密码的泄漏
  2. 令牌上可以设定访问资源的范围以及时效性
  3. 每个应用都持有独立的令牌,哪个失效都不会波及其他

OAuth2.0一共提出了四种不同的授权方式:

  • 授权码模式(Authorization Code)
  • 隐式授权模式(Implicit)
  • 密码模式(Resource Owner Password Credentials)
  • 客户端模式(Client Credentials)

本文介绍和实现的是授权码方式。

OAuth2.0流程图

  1. client请求授权服务端,获取Authorization Code;
  2. client通过Authorization Code再次请求授权服务端,获取Access Token;
  3. client通过服务端返回的Access Token获取用户的基本信息。

流程图如下所示:

请添加图片描述

第一次使用github账号应用来登陆掘金,需要进行授权

掘金即是第三方应用, 请求GitHub。

请添加图片描述

注册一个新的OAuth Application

如果我们需要使用GitHub账号来关联我们自己的第三方应用则需要完整走一遍OAuth2.0流程。

请添加图片描述

GitHub生成的client_id, client_secret(密钥), redirect_uri, homepage_url, application_name等等。

请添加图片描述

clientId如何生成唯一的

在注册clientId以及申请clientSecret时,如何保证生成的clientId是不重复的呢?

和JWT以及Cookie-Session对比

参考《凤凰架构》架构安全篇 https://icyfenix.cn/architect-perspective/general-architecture/system-security/authorization.html

谈谈State参数为什么可以防止CSRF攻击

观察GitHub OAuth2.0实现文档,可以观察到在authroize接口需要传递一个state参数,并且在redirect_uri重定向时原封不动传递回来,所以为什么可以防止CSRF攻击呢?

请添加图片描述

核心: 在于授权服务端进行token请求绑定时,会从session将本次会话的账号与生成access_token进行绑定,而对于用户是谁并不关心。

案例
请添加图片描述

  1. 用户B登录掘金网站,并且选择绑定自己的GitHub账号;
  2. 掘金网站将用户B重定向到GitHub,由于他之前已经登录过GitHub,所以GitHub直接向他显示是否授权掘金访问的页面;
  3. 用户B在点击"同意授权"之后,截获GitHub服务器返回的含有authorization code参数的HTTP响应;
  4. 用户B精心构造一个Web页面,它会触发掘金网站向GitHub发起令牌申请的请求,而这个请求中的authorization code
    参数正是上一步截获到的code;
  5. 用户B将这个Web页面放到互联网上,等待或者诱骗受害者用户A来访问;
  6. 用户A之前登录了掘金
    网站,只是没有把自己的账号和其他社交账号绑定起来。在用户A访问了用户B准备的这个Web页面,令牌申请流程在用户A的浏览器里被顺利触发,掘金
    网站从GitHub那里获取到access_token,但是这个token以及通过它进一步获取到的用户信息却都是攻击者用户B;
  7. 掘金网站将用户B的GitHub账号同用户A的掘金账号关联绑定起来,从此以后,用户B就可以用自己的GitHub账号通过OAuth
    登录到用户A在掘金网站中的账号,堂而皇之的冒充用户A的身份执行各种操作;

代码实现(知识碎片总结)

本部分将开发过程中遇到的难点记录下来,具体源码参考此repo 👍

postman 请求共享session问题

本文为单体应用,使用了HttpServletRequestHttpSession方便开发,将相关的数据保存在服务器的Session中,但是Postman在发送请求的时候,
不会将其视为同一个连接,导致获取不到Session中的数据,需要每次将用户登陆的Cookie赋值到相应的接口上才能获取到Session中的数据。

请添加图片描述

实现HandlerInterceptor接口完成请求过滤

涉及到接口请求过滤条件时,可以通过实现WebMvcConfigurer接口来添加过滤规则,例如:

  1. 授权前用户没有登陆则需要重定向到登陆页面
  2. 如果access_token过期,则需要重新获取
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    //注意注入bean的写法
    @Bean
    public OauthInterceptor oauthInterceptor() {
        return new OauthInterceptor();
    }

    @Bean
    public AuthAccessTokenInterceptor accessTokenInterceptor() {
        return new AuthAccessTokenInterceptor();
    }

    @Bean
    public LoginInterceptor loginInterceptor() {
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor()).addPathPatterns("/user/**", "/oauth2.0/authorizePage", "/oauth2.0/authorize", "/sso/token");
        registry.addInterceptor(oauthInterceptor()).addPathPatterns("/oauth2.0/authorize");
        registry.addInterceptor(accessTokenInterceptor()).addPathPatterns("/api/**");
    }
}

参考资料

  • https://icyfenix.cn/architect-perspective/general-architecture/system-security/
  • https://time.geekbang.org/column/intro/100039001
  • https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps
  • https://juejin.cn/post/6844903668861534215#heading-4
  • https://www.jianshu.com/p/c7c8f51713b6

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧农场物联网系统:重塑农业的未来

随着科技的进步,物联网技术正在逐渐改变我们的生活。在农业领域,物联网系统也正在发挥着越来越重要的作用,为智慧农场的发展提供了新的可能。本文将深入探讨智慧农场物联网系统的优势、应用场景、技术实现以及未来发展趋势。 一、智慧农场物…

Java Web这一路走来

大部分Java应用都是Web或网络应用,MVC框架在Java框架中有着举足轻重的地位,一开始的Web应用并不现在这样子的,一步一步走来,每一步都经历了无数的血和泪的教训,以史为镜可以知兴替。 1. 草莽时代 早期的Java服务端技…

只有线上出了bug,老板们才知道测试的价值?

有同学说,测试没价值,我们测试团队刚被拆散了。 也有同学说,公司不重视测试,我觉得我们就是测试得太好了。哪天线上出个bug,老板们就知道测试的价值了。 还有人给测试同学规划职业发展路径,就是不做测试&…

蓝桥杯算法题:练功

【问题描述】 小明每天都要练功,练功中的重要一项是梅花桩。 小明练功的梅花桩排列成 n 行 m 列,相邻两行的距离为 1,相邻两列的距离也为 1。 小明站在第 1 行第 1 列上,他要走到第 n 行第 m 列上。小明已经练了一段时间&#xff…

【IC前端虚拟项目】spyglass lint环境组织与lint清理

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 和上个虚拟项目的lint清理环节一样,关于spyglass的lint清理功能与流程还是大家通过各种资料去学习下就好啦。和之前不同的事,这次的虚拟项目里我把流程封装为Makefile,…

中老年人购买需求不断上升,下一个电商新风口又会在哪里?

大家好,我是电商花花。 电商互联网时代,不再是年轻人的刚需。 中老年消费市场与日俱增,据统计,我国中老年人口已近10亿,占比巨大,且呈上升趋势。 50、60后的中老年人入网率已然在加快提升,相…

提示工程中的10个设计模式

我们可以将提示词定义为向大型语言模型(Large Language Model,LLM)提供的一个查询或一组指令,这些指令随后使模型能够维持一定程度的自定义或增强,以改进其功能并影响其输出。我们可以通过提供细节、规则和指导来引出更有针对性的输出&#x…

HDLbits 刷题 --Reduction

Given a 100-bit input vector [99:0], reverse its bit ordering. 译&#xff1a; 给定一个100位的输入向量 [99:0]&#xff0c;反转其位的顺序。 module top_module( input [99:0] in,output [99:0] out );integer i;always(*) beginfor(i0;i<100;i)out[99-i]in[i];end…

如何使用ChatGPT制作一个休闲小游戏集合的网站?

1. 先看制作的网站效果 先预览一个使用ChatGPT制作的休闲小游戏集合网站&#xff1a;CasualMiniGame.com 2. 使用描述词生成网站首页 使用ChatGPT生成一个在线的休闲小游戏网站是一项有趣的任务。ChatGPT可以生成代码&#xff0c;展示您输入的描述词对应的网站效果。以下是Ch…

Metasploit Pro 4.22.3-2024040301 (Linux, Windows) - 专业渗透测试框架

Metasploit Pro 4.22.3-2024040301 (Linux, Windows) - 专业渗透测试框架 Rapid7 Penetration testing, Release Apr 03, 2024 请访问原文链接&#xff1a;Metasploit Pro 4.22.3-2024040301 (Linux, Windows) - 专业渗透测试框架&#xff0c;查看最新版。原创作品&#xff0…

希亦、添可、追觅洗地机深入对比,哪个更胜一筹?选择不再迷茫

洗地机不仅能快速打扫地面&#xff0c;省时又省力&#xff0c;还能把室内弄得干干净净的&#xff0c;用起来感觉特舒服。但是面对目前市面上几百个型号的洗地机&#xff0c;在观望洗地机的家庭&#xff0c;大多数都是不确定哪款洗地机适合自己&#xff0c;今天笔者就带来了三款…

【NLP练习】中文文本分类-Pytorch实现

中文文本分类-Pytorch实现 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、准备工作 1. 任务说明 本次使用Pytorch实现中文文本分类。主要代码与文本分类代码基本一致&#xff0c;不同的是本次任务使用…

【学习心得】Python中的queue模块使用

一、Queue模块的知识点思维导图 二、Queue模块常用函数介绍 queue模块是内置的&#xff0c;不需要安装直接导入就可以了。 &#xff08;1&#xff09;创建一个Queue对象 import queue# 创建一个队列实例 q queue.Queue(maxsize20) # 可选参数&#xff0c;默认为无限大&am…

libVLC 提取视频帧使用QWidget渲染

在前面的文章中&#xff0c;我们使用libvlc_media_player_set_hwnd设置了视频的显示的窗口。 libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui.widgetShow->winId()); 如果我们想要提取每一帧数据&#xff0c;将数据渲染到QWidget上&#xff0c;该如何操作呢&a…

西圣、漫步者、万魔开放式耳机怎么样?无广真实测评对比推荐

开放式耳机因其独特的音质体验和佩戴舒适度&#xff0c;受到了越来越多消费者的青睐。西圣、漫步者、万魔作为国内知名的耳机品牌&#xff0c;各自都推出了自家的开放式耳机产品&#xff0c;那么&#xff0c;这三款耳机究竟如何呢&#xff1f;身为开放式耳机党的我&#xff0c;…

小白如何挖到自己的第一个漏洞

目录 挖洞公式 个人介绍 我的技术与生活——小站首页 | Hexohttps://xiaoyunxi.wiki/ 漏洞介绍 漏洞详情 如何进行信息收集(最快捷) 方法1(Google Hacking) 0x01 常见Google语法 0x02 不是经常用的关键字 0x03 特殊符号使用 0x04 布尔操作 0x05注意事项 0x06 使用…

【C++ STL算法】sort 排序

文章目录 【 1. 基本原理 】【 2. sort 的应用 】实例 - sort 函数实现 升序排序和降序排序 函数名用法sort (first, last)基于 快速排序&#xff0c;对容器或普通数组中 [ first, last ) 范围内的元素进行排序&#xff0c;默认进行升序排序&#xff08;从小到大&#xff09;。…

在linux上面安装nexus私有maven库

问题 需要在EC2机器上面安装私有maven库。 步骤 更新OS sudo yum update -yJDK11 # 安装JDK11 sudo yum install java-11-amazon-corretto # 查询jdk11位置 sudo alternatives --config java内容如下&#xff1a; There are 2 programs which provide java.Selection …

用动态IP采集数据总是掉线是为什么?该怎么解决?

动态IP可以说是做爬虫、采集数据、搜集热门商品信息中必备的代理工具&#xff0c;但在爬虫的使用中&#xff0c;总是会遇到动态IP掉线的情况&#xff0c;从而影响使用效率&#xff0c;本文将探讨动态IP代理掉线的几种常见原因&#xff0c;并提供解决方法&#xff0c;以帮助大家…

libVLC 提取视频帧使用OpenGL渲染

在上一节中&#xff0c;我们讲解了如何使用QWidget渲染每一帧视频数据。 由于我们不停的生成的是QImage对象&#xff0c;因此对 CPU 负荷较高。其实在绘制这块我们可以使用 OpenGL去绘制&#xff0c;利用 GPU 减轻 CPU 计算负荷&#xff0c;本节讲解使用OpenGL来绘制每一帧视频…