构建简单OAuth授权服务器

Spring Security OAuth2 入门,linux操作系统学习 在授权码模式下,允许为空。 可能有部分胖友是 Windows 电脑,可以参考 《windows(64位)下使用 curl 命令》 来安装一个 curl 命令。 当然,如果胖友使用 Postman ,可以参看如下两图: 图 1 图 2 ⑥ 调用资源服务器的 API curl -X GET http://localhost:8080/api/example/hello -H “authorization: Bearer e60e41f2-2ad0-4c79-97d5-49af38e5c2e8” . 阅读详情

构建简单OAuth授权服务器

授权服务器是OAuth生态系统中最复杂的组件,它是整个OAuth系统中安全权威中心,只有授权服务器能够对用户进行认证,注册客户端,颁发令牌。OAuth2.0规范制定中已经尽可能将复杂性从客户端和受保护资源转移至授权服务器

管理OAuth客户端注册

向授权服务器注册客户端信息,可以开发web界面维护客户端信息,也可以初始化。这里我们使用静态注册便于观察学习

    var clients = [
    {
        "client_id": "oauth-client-1",
        "client_secret": "oauth-client-secret-1",
        "redirect_uris": ["http://localhost:9000/callback"],
    }
    ];
    var getClient = function(clientId){
        return __.find(clients, function(client){return client.client_id == clientId;})
    }

对客户端授权

OAuth授权要求授权服务器提供两个端点:授权端点,运行在前端信道上;令牌端点,运行在后端信道上

授权端点

用户在OAuth授权过程中第一站是授权端点,授权端点是一个前端信道端点,客户端会将用户浏览器重定向至该端点,以发出授权请求

    app.get("/authorize", function(req, res){
        var client = getClient(req.query.client_id);
        if(!client){
            console.log("Unknown client %s", req.query.client_id);
            res.render('error', {error: 'Unknow client'});
            return;
        } else if(!__.contains(client.redirect_uris, req.query.redirect_uri)){
            console.log('Mismatched redirect URI, expected %s got %s', client.redirect_uris, req.query.redirect_uri);
            res.render('error', {error: 'Invalid redirect URI'});
            return;
        } else {
            var reqid = reandomstring.generate(8);
            requests[reqid] = req.query;
            res.render('approve', {client: client, reqid: reqid});
            return;
        }
    });

客户端授权

    app.post('/approve', function(req, res){
        var reqid = req.body.reqid;
        var query = requests[reqid];
        delete requests[reqid];
        if(!query){
            res.render('error', 'No matching authorization request');
            return;
        }
        if(req.body.approve){
            if(query.response_type == 'code'){
                var code = randomstring.generate(8);
                codes[code] = {request: query};
                var urlParsed = buildUrl(query.redirect_uri, {
                    code: code,
                    state: query.state
                });
                res.redirect(urlParsed);
                return;
            } else {
                var urlParsed = buildUrl(query.redirect_uri, {
                    error: 'unsupported_response_type'
                });
                res.redirect(urlParsed);
                return;
            }
        }
    });

令牌颁发

客户端拿到授权码后,向授权服务器的令牌端点发送POST请求,去访问令牌

对客户端进行身份认证、处理授权许可请求

    app.post("/token", function(req, res){
        //  获取客户端凭证
        var auth = req.headers['authorization'];
        if(auth){
            var clientCredentials = decodeClientCredentials(auth);
            var clientId = clientCredentials.id;
            var clientSecret =clientCredentials.secret;
        }
        if(req.body.client_id){
            if(clientId){
                console.log('Client attempte to authenticate with multiple methods');
                res.status(401).json({error: 'invalid_client'});
                return;
            }
            var clientId = req.body.client_id;
            var clientSecret = req.body.client_secret;
        }
        //从数据库加载客户端
        var client = getClient(clientId);
        if(!client){
            console.log('Unknown client %s', clientId);
            res.status(401).json({error: 'invalid_client'});
            return;
        }
        if(req.body.grant_type == 'authorization_code'){//判断授权类型
            var code = codes[req.body.code];            //获取之前生成授权码时存储的信息
            if(code){
                delete codesp[req.body.code];           //去除使用过的授权码
                if(code.rquest.client_id == clientId){  //判断获取token客户端是不是对应授权码客户端
                    var access_token = randomstring.generate();
                    nosql.insert({access_token: access_token, client_id: clientId});
                    console.log('Issuing access token %s', access_token);
                    var token_response = {access_token: access_token, token_type: 'Bearer'};
                    res.status(200).json(token_response);
                    console.log('Issued token for code %s', req.body.code);
                    return;
                } else {
                    console.log('Client mismatch, expected %s got %s', code.request.client_id, clientId);
                    res.status(400).json({error: 'invalid_grant'});
                    return;
                }
            } else {
                console.log('Unknown code, %s', req.boy.code);
                res.status(400).json({error: 'invalid_grant'});
                return;
            }
        } else {
            console.log('Unknown grant type %s', req.body.grant_type);
            res.status(400).json({error: 'unsupported_grant_type'});
        }
    });

支持刷新令牌

    app.post("/token", function(req, res){
        //  获取客户端凭证
        var auth = req.headers['authorization'];
        if(auth){
            var clientCredentials = decodeClientCredentials(auth);
            var clientId = clientCredentials.id;
            var clientSecret =clientCredentials.secret;
        }
        if(req.body.client_id){
            if(clientId){
                console.log('Client attempte to authenticate with multiple methods');
                res.status(401).json({error: 'invalid_client'});
                return;
            }
            var clientId = req.body.client_id;
            var clientSecret = req.body.client_secret;
        }
        //从数据库加载客户端
        var client = getClient(clientId);
        if(!client){
            console.log('Unknown client %s', clientId);
            res.status(401).json({error: 'invalid_client'});
            return;
        }
        if(req.body.grant_type == 'authorization_code'){//判断授权类型
            var code = codes[req.body.code];            //获取之前生成授权码时存储的信息
            if(code){
                delete codesp[req.body.code];           //去除使用过的授权码
                if(code.rquest.client_id == clientId){  //判断获取token客户端是不是对应授权码客户端
                    var access_token = randomstring.generate();
                    nosql.insert({access_token: access_token, client_id: clientId});
                    console.log('Issuing access token %s', access_token);
                    var token_response = {access_token: access_token, token_type: 'Bearer'};
                    res.status(200).json(token_response);
                    console.log('Issued token for code %s', req.body.code);
                    return;
                } else {
                    console.log('Client mismatch, expected %s got %s', code.request.client_id, clientId);
                    res.status(400).json({error: 'invalid_grant'});
                    return;
                }
            } else {
                console.log('Unknown code, %s', req.boy.code);
                res.status(400).json({error: 'invalid_grant'});
                return;
            }
        }  else if(req.body.grant_type == 'refresh_token'){
            nosql.one(function(token){
                if(token.refresh_token == req.body.refresh_token){
                    return token;
                }
            }, function(err, token){
                if(token){
                    console.log('We found a matching refresh token: %s', req.body.refresh_token);
                    if(token.clinet_id != clientId){
                        nosql.remove(function(found){return (found == token)}, function(){});
                        res.status(400).json({error: 'invalid_grant'});
                        return;
                    }
                    var access_token = randomstring.generate();
                    nosql.insert({access_token: access_token, client_id: clientId});
                    var token_response = {access_token: access_token, token_type: 'Bearer', refresh_token: token.refresh_token};
                    res.status(200).json(token_response);
                } else {
                    console.log('No matching token was found.');
                    res.status(400).json({error: 'invalid_grant'});
                    return;
                }
            })
        } else {
            console.log('Unknown grant type %s', req.body.grant_type);
            res.status(400).json({error: 'unsupported_grant_type'});
        }
    });

增加授权范围支持

OAuth2.0很重要的机制就是权限范围。首先通常需要限制每个客户端在服务器上可访问范围,防止客户端不当行为,使得系统能限制客户端只能在受保护资源上执行特定操作,我们需要为客户端添加scope字段,存储客户端权限范围,权限之间以空分割,之所以要使用空格分割,而不是使用数组等复杂结构,是因为HTTP表单和查询参数没有一种很好的方式表示像数组和对象这样的复杂结构,然而OAuth又需要使用查询参数通过前端信道来传达信息。

OAuth2授权服务器和四种授权方式 OAuth2授权服务器和四种授权方式1 问题描述2 授权服务器实现2.1 创建工程2.2 授权相关的配置2.3 认证相关的配置2.4 用户信息获取2.5 主启动类2.6 其它配置3 四种授权方式的测试3.1 授权码授权方式3.1.1 配置说明3.1.2 测试步骤3.2 密码授权方式3.2.1 配置说明3.2.2 测试步骤3.3 简化授权方式3.3.1 配置说明3.3.2 测试步骤3.4 客户端授权... 阅读详情

相关推荐

OAuth2.0四种授权模式以及Oauth2.0实战

Oauth2.0具有多种授权许可机制协议:授权码许可机制、客户端凭据机制、资源拥有者凭据机制(密码模式)和隐式许可机制。在源码中即可看到四种模式的实现类,还有一个RefreshTokenGranter则是刷新令牌,用于access_token失效时刷新过期时间。假如现在我需要实现手机验证码登录或者微信扫码登录等功能的时候,我们该如何处理呢?我们可以继承AbstractTokenGranter实现自定义授权模式。手机短信验证码模式@Slf4j@Override。

周沐子 3238

OAuth2:搭建授权服务器

OAuth2:搭建授权服务器

Leon_Jinhai_Sun的博客 3889

SpringSecurity认证服务器:OAuth2授权服务器实现

OAuth2授权服务器默认使用JWT作为访问令牌格式。@Component@Override// 添加用户角色// 添加其他自定义声明@BeanSpring Authorization Server为构建OAuth2授权服务器提供了强大而灵活的支持。通过适当的配置,可以快速实现一个功能完备的认证授权中心,支持多种授权类型和客户端认证方法。本文介绍了Spring Authorization Server的基础配置、客户端注册、用户认证、令牌定制以及授权确认页面的定制方法。

程序媛学姐的博客 2455

一步一步搭建 OAuth 认证服务器

现在越来越多开放的互联网公司提供对外的 API 接口,使得第三方应用开发人员可以开发基于该平台接口的应用程序。国外有Twitter、Flicker Service等;国内的,像腾讯微博开放平台、新浪微博开放平台等等。 这些平台接口的认证方式,无一例外的,都采取了 OAuth 来实现(Twitter原来使用的是Basic Auth方式,后来全面转向OAuth)。 那么,OAuth 是

leeyisoft的专栏 1928

SpringSecurity OAuth2:授权服务器与资源服务器配置

Spring Security OAuth2提供了强大而灵活的机制,用于实现标准化的授权服务器和资源服务器。通过合理配置授权服务器,开发者可以自定义客户端注册、授权类型、令牌策略等,满足不同应用场景的需求。令牌存储策略的选择应基于系统性能、安全性和部署环境等因素,JWT令牌因其自包含特性在微服务架构中尤为适用。资源服务器配置则专注于保护API资源,通过URL级别和方法级别的安全控制,确保只有持有有效令牌且具备适当权限的请求才能访问受保护资源。

程序媛学姐的博客 2383

10、构建简单的OAuth授权服务器指南

本文详细介绍了如何构建一个简单的OAuth授权服务器,涵盖了客户端授权准备、授权端点和令牌端点的构建、用户授权处理、令牌颁发以及相关安全性考虑。同时提供了优化建议,以增强服务器的安全性和性能。

rgv23456789的博客 59

oauth服务器搭建 java_JAVA Oauth 认证服务器的搭建

http://blog.youkuaiyun.com/binyao02123202/article/details/122044111、软件下载2、服务端源码下载后,把相关代码整合在一起(或直接下载站长整合好的代码),修改net.oauth.provider.core.SampleOAuthProvider 类,把从 provider.properties 读取的信息改为从数据库中读取,如APP_KEY、A...

weixin_39599654的博客 148

10、构建简单的 OAuth 授权服务器指南

本文详细介绍了如何构建一个简单的 OAuth 授权服务器,涵盖了客户端信息准备、授权端点和令牌端点的实现、用户授权处理以及常见问题的解决方案。同时,还提供了扩展与优化建议,帮助开发者更好地理解和实现 OAuth 协议的核心流程和相关功能。

d6e7f8g9h的博客 53

linux软件运行授权,使用控制台程序搭建OAuth授权服务器

详细讲解使用控制台程序搭建OAuth授权服务器,先上一张OAuth的认证图很多情况下授权服务器和资源服务器时同一台机器,就有了下面这张图接着可以使用上一篇文章中的控制台程序,做一些改动首先需要引入Microsoft.AspNet.Identity.Owin包PM> Install-Package Microsoft.AspNet.Identity.Owin -Pre添加一个授权提供类Appl...

weixin_39984952的博客 196

11、构建简单的OAuth授权服务器指南

本文详细介绍了如何构建一个简单的OAuth授权服务器,涵盖OAuth授权服务器的基础概念、刷新令牌的支持、范围控制的实现以及相关的安全防护措施。通过具体的代码示例和操作步骤,帮助开发者快速搭建一个功能完备的OAuth授权服务器,并实现客户端身份验证、用户授权、访问令牌发放等功能。此外,文章还分析了构建过程中可能遇到的常见问题及其解决方案,并展望了OAuth授权服务器在未来应用中的发展趋势。

rgv23456789的博客 66

7、构建简单OAuth客户端指南

本文详细介绍了如何构建一个简单的OAuth客户端,涵盖向授权服务器注册客户端、使用授权码授权类型获取访问令牌、访问受保护资源以及刷新令牌等步骤。同时,还讨论了不同客户端类型和授权类型的适用场景及安全注意事项,帮助开发者更好地理解和应用OAuth协议。

rgv23456789的博客 59

使用Spring Boot构建独立的OAuth服务器(一)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34037515的博客 201

Mac用户必看:Parallels Desktop 18.1.1最新破解版安装与优化全攻略(附资源)

本文为Mac用户提供Parallels Desktop 18.1.1的详细安装与优化指南,涵盖虚拟化技术选型、专业级配置流程及性能调优技巧。重点解析Parallels Desktop在图形加速、系统资源调度方面的核心优势,并分享生产力增强技巧与典型应用场景实战方案,帮助用户最大化利用这一高效虚拟化工具。

weixin_29240343的博客 829

Node OAuth2 服务器示例项目介绍

Node OAuth2 服务器示例项目介绍 1. 项目基础介绍与主要编程语言 Node OAuth2 服务器示例项目是一个基于 Node.js 的开源项目,旨在提供一个配置最少的 OAuth2 服务器实现。该项目使用 JavaScript 作为主要编程语言,并利用了 node-oauth2-server 库来构建 OAuth2 服务器。 2. 项目的核心功能 该项目的核心功能是提供了一个 OAut...

gitblog_01066的博客 343

nRF52840开发环境搭建:从零开始配置Keil与SDK

本文详细介绍了nRF52840开发环境搭建的全过程,包括硬件准备、Keil MDK与nRF5 SDK的安装配置、常见问题解决方案及蓝牙功能开发进阶。特别强调了J-Link调试器的使用和SDK版本匹配的重要性,帮助开发者快速上手nRF52840开发。

weixin_29176179的博客 886

4.3 Langfuse 集成实战:追踪 OpenAI、LangChain 和 LangGraph 应用

本文介绍了如何将Langfuse集成到不同类型的AI应用中,包括原生OpenAI、LangChain和LangGraph应用。主要内容包括: 两种集成模式:手动追踪(精确控制)和自动追踪(通过回调机制) 三种应用场景的集成方案: 原生OpenAI应用:使用langfuse.trace()手动记录对话流程、LLM调用和工具执行 LangChain应用:通过LangfuseCallbackHandler自动追踪Agent执行过程 LangGraph应用:与LangChain相同的自动追踪方式,可可视化节点和状态

yonggeit的博客 3305

搭建spring security oauth2认证授权服务器

搭建spring security oauth2认证授权服务器

qq_36551991的博客 3754

go语言实现服务器server端与客户client端即时通信(附完整源码)

go语言实现服务器server端与客户client端即时通信(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 631

从零到一:用Java和Spring Security构建OAuth2授权服务器

本文将带领读者从零开始,使用Java和Spring Security框架构建一个功能完整的OAuth2授权服务器,深入理解OAuth2的核心概念和实现细节。

exlink2012的专栏 1911

自然语言处理(扩展学习1):Scheduled Sampling(计划采样)与Teacher forcing(教师强制)

作者:安静到无声作者简介:人工智能和硬件设计博士生、优快云与阿里云开发者博客专家,多项比赛获奖者,发表SCI论文多篇。o( ̄▽ ̄)d。

安静到无声 2145

PCL CSF布料模拟算法【2026最新版】

CSF布料模拟地面滤波算法的PCL实现,博客长期更新,本文最近更新时间为:2026年10月26日。

点云侠的博客 3919

Spring security OAuth2 授权服务器搭建

基于 spring security oauth2 搭建授权服务器,基于里面四种模式分别都有介绍以及如何使用

冬阳 2723

Pytorch实现EdgeCNN(基于PyTorch实现)

本专栏整理了《图神经网络代码实战》,内包含了不同图神经网络的相关代码实现(PyG以及自实现),理论与实践相结合,如GCN、GAT、GraphSAGE等经典图网络,每一个代码实例都附带有完整的代码。

优快云 精品推荐 1万+

使用 Vue.js 构建 OAuth2 授权同意页面

本文介绍了在前后端分离项目中如何使用Vue.js构建OAuth2授权同意页面,结合Spring Authorization Server和Spring Security构建OAuth2服务器和客户端。

new_ord的博客 2062

基于Python的电商平台商品信息爬取与价格监控系统设计与实现

本文详细介绍了一个基于Python的电商平台商品信息爬取与价格监控系统的设计与实现。系统采用最新的Python爬虫技术栈,包括Scrapy框架、Selenium自动化测试工具、BeautifulSoup解析库等,实现了对主流电商平台商品信息的自动化采集、存储、分析和可视化展示。文章从系统架构设计、关键技术实现、核心代码解析等方面进行了全面阐述,并提供了完整的代码实现。该系统不仅适用于毕业设计,也可作为商业价格监控系统的原型。关键词:Python爬虫;电商数据采集;价格监控;Scrapy;Selenium;

2201_76125261的博客 964

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: 构建简单的OAuth受保护资源
下一篇: 现实世界中的OAuth2.0
炒栗子不加糖
博客等级 码龄10年 68粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值