热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于IdentityServer4的OAuth2.0授权(客户端模式)

IdentityServer4是为ASP.NETCore2.系列量身打造的一款基于OpenIDConnect和OAuth

IdentityServer4 是为ASP.NET Core 2.系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证框架。

官网地址:http://www.identityserver.com.cn/

基础知识

什么是 OAuth 2.0?OpenID Connect又是什么?如果有兴趣可以深入研究下。这里就不展开了,大致有个了解就行,本文主要是介绍基于IdentityServer4中间件来快速实现一个OAuth2.0的授权,保护API资源。如果你选择通过直接发送和处理 HTTP 请求或使用第三方开源库来编写代码,而不是使用中间件来实现,就需要去研究下标准协议了。

IdentityServer4可以帮助你做什么?

IdentityServer是将规范兼容的OpenID Connect和OAuth 2.0端点添加到任意ASP.NET Core应用程序的中间件。通常,您构建(或重新使用)包含登录和注销页面的应用程序,IdentityServer中间件会向其添加必要的协议头,以便客户端应用程序可以与其对话 使用这些标准协议。

专业术语

用户(User)
用户是使用已注册的客户端(指在id4中已经注册)访问资源的人。

客户端(Client)

客户端就是从identityserver请求令牌的软件(你可以理解为一个app即可),既可以通过身份认证令牌来验证识别用户身份,又可以通过授权令牌来访问服务端的资源。但是客户端首先必须在申请令牌前已经在identityserver服务中注册过。

实际客户端不仅可以是Web应用程序,app或桌面应用程序(你就理解为pc端的软件即可),SPA,服务器进程等。

资源(Resources)

资源就是你想用identityserver保护的东东,可以是用户的身份数据或者api资源。

身份令牌(顾名思义用于做身份认证)
一个身份令牌指的就是对认证过程的描述。它至少要标识某个用户(Called the sub aka subject claim)的主身份信息,和该用户的认证时间和认证方式。但是身份令牌可以包含额外的身份数据,具体开发者可以自行设定,但是一般情况为了确保数据传输的效率,开发者一般不做过多额外的设置,大家也可以根据使用场景自行决定。

访问令牌(用于做客户端访问授权)
访问令牌允许客户端访问某个 API 资源。客户端请求到访问令牌,然后使用这个令牌来访问 API资源。访问令牌包含了客户端和用户(如果有的话,这取决于业务是否需要,但通常不必要)的相关信息,API通过这些令牌信息来授予客户端的数据访问权限。

具备如下的特点:

  1. 认证服务,可以为你的应用(如网站、本地应用、移动端、服务)做集中式的登录逻辑和工作流控制。IdentityServer是完全实现了OpenID Connect协议标准。

  2. 单点登录登出(SSO),在各种类型的应用上实现单点登录登出。

  3. API访问控制,为各种各样的客户端颁发access token令牌,如服务与服务之间的通讯、网站应用、SPAS和本地应用或者移动应用。

  4. 联合网关,支持来自Azure Active Directory, Google, Facebook这些知名应用的身份认证,可以不必关心连接到这些应用的细节就可以保护你的应用。

  5. 专注于定制,最重要的是identityserver可以根据需求自行开发来适应应用程序的变化。identityserver不是一个框架、也不是一个盒装产品或一个saas系统,您可以编写代码来适应各种场景。

  6. 成熟的开源系统,IdentityServer拥有apache 2 授权许可,允许构建商业化的应用,也是.net基金会组织的成员之一,并为其提供法律支持。

  7. 免费和商业支持

授权模式

OAuth2.0 定义了四种授权模式:

  • 简化模式

  • 客户端凭证模式

  • 密码模式

  • 授权码模式

项目构成

一般分为IdentityServer、API资源服务、第三方客户端(app),并且都是独立的。所以我们要分别建立三个项目:

  • 颁发授权的服务,也就是说要访问特定的API资源必须经过该服务进行授权验证。

  • API资源的项目,这是客户端实际要访问的API资源,比如:平台的openapi。

如下图:


这里我就偷懒了只新建了两个项目,WebOAuthDemo.Server是AuthorizationServer,WebOAuthDemo.WebApi是webAPI资源服务,第三方客户端可以用postman来模拟请求。

客户端授权

新建IdentityServer项目

取名为WebOAuthDemo.Server

  • 包管理器中安装IdentityServer4,我用的版本是3.1.3,现在4.+预览版已经有了。

PM>Install-Package IdentityServer4 -Version 3.1.3

  • 新建一个Config文件,添加一个获取API资源的静态方法,如下:

public static IEnumerable GetApiResources()
{
return new[]
{
new ApiResource("clientservice", "CAS Client Service"),
new ApiResource("productservice", "CAS Product Service"),
new ApiResource("agentservice", "CAS Agent Service")
};
}

正常环境下,API资源是通过服务注册到指定地方,比如数据库中,然后通过接口获取所有API的资源列表,这里代码中写死得了。

  • Config类中再添加一个获取客户端列表的静态方法

public static IEnumerable GetClients()
{
return new[]
{
new Client
{
ClientId = "client.api.service",
ClientSecrets = new [] { new Secret("clientsecret".Sha256()) },
//客户端授权类型,用户密码模式
AllowedGrantTypes=GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = new [] { "clientservice" }
}
};
}

同理,第三方客户端是通过某种方式添加到数据库中进行持久化管理,这里也只是测试,简化了第三方授权和生成appid,appSecret等业务逻辑。

  • 修改Startup.cs 为了让 IdentityServer 使用你的Scopes和客户端定义,你需要向ConfigureServices 方法中添加一些代码

public void ConfigureServices(IServiceCollection services)
{
//使用内存存储,密钥,客户端和资源来配置身份服务器。
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());

services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}

修改Configure方法,启用IdentityServer

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//启用IdentityServer
app.UseIdentityServer();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

  • 运行项目

浏览器输入[http://localhost:59234/.well-known/openid-configuration],可以看到下图所示: 

  • 获取token

我们用Postman发送请求测试是否能获取到token,输入Url[http://localhost:59234/connect/token],请求body当中输入参数:

client_idclient.api.service //appid
client_secretclientsecret //appsecret
grant_typeclient_credentials //客户端模式

结果是成功的,如下图所示: 

那接下来我们新建一个API资源客户端。

新建API资源项目

取名WebOAuthDemo.WebApi,Nuget包管理控制台,安装IdentityServer4.AccessTokenValidation

PM>Install-Package IdentityServer4.AccessTokenValidation -Version 3.0.1

  • 修改Startup.cs

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(Configuration["Identity:Scheme"])
.AddIdentityServerAuthentication(options =>
{
options.RequireHttpsMetadata = false;
options.Authority = $"http://{Configuration["Identity:IP"]}:{Configuration["Identity:Port"]}";
options.ApiName = Configuration["Service:Name"];
});
services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//启用Authentication中间件
app.UseAuthentication();

app.UseRouting();

app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

appsetings.json加上如下配置,可根据自己的需求修改:

"Service": {
"Name": "clientservice", //本服务的名称
"Port": "60806", //本服务的端口号,根据自己服务启动时的端口号进行更改
"DocName": "clientservice",
"Version": "v1",
"Title": "CAS Client Service API",
"Description": "CAS Client Service API provide some API to help you get client information from CAS",
"Contact": {
"Name": "zhanwei",
"Email": "zhanwei103@126.com"
}
},
"Identity": { //去请求授权的Identity服务,这里即IdentityServerDemo的服务启动时的地址
"IP": "localhost",
"Port": "59234", //IdentityServerDemo项目启动时的端口号,根据实际情况修改
"Scheme": "Bearer"
}

  • 控制器 添加一个新的控制器到你的 API 项目中:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}

  • 运行API项目

我们试着Postman中发送API请求,返回的是401 Unauthorized

  • 加上token再进行请求,结果如下图:

密码模式

修改WebOAuthDemo.Server项目

  • Config类中再添加一个获取客户端列表的静态方法

public static IEnumerable GetUsers()
{
return new[]
{
new TestUser
{
SubjectId = "10001",
Username = "test1@163.com",
Password = "test1password"
},
new TestUser
{
SubjectId = "10002",
Username = "test2@163.com",
Password = "test2password"
}
};
}

  • 增加一些测试用户,然后修改ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddTestUsers(Config.GetUsers().ToList())//注入测试用户
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());

services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}

  • 重新运行IdentityServer项目 Postman发送请求,此时已经能够通过密码获取到token了,请求参数如下

client_idclient.api.service //appid
client_secretclientsecret //appsecret
grant_typepassword //密码模式
usernametest1@163.com
passwordtest1password

  • 结果如下图所示:

  • API项目不需要修改,只不过是第三方客户端请求token的参数变了,其他基本和客户端模式一样,这里就不重复了。

过程总结:

  • 首先,在授权服务中,设置需要请求的ApiResource,client,user

  • 在postman(相当于client)中,输入client的相关信息(client_id,client_serect)去请求token

  • 然后就可以根据授权服务中相应client的AllowedScopes设置的范围来请求服务了。

另外,IdentityServer提供了个QuickStartUI的项目,这套UI能快速的开发具有基本功能的认证/授权界面,可以下载下来研究下。

下载地址:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/

下一篇准备写一下OAuth2.0的授权码模式,这是一种混合模式,是目前功能最完整、流程最严密的授权模式,也是最常用的一种模式,安全性也高,适用于那些有后端的Web 应用。




推荐阅读
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文介绍了禅道作为一款国产开源免费的测试管理工具的特点和功能,并提供了禅道的搭建和调试方法。禅道是一款B/S结构的项目管理工具,可以实现组织管理、后台管理、产品管理、项目管理和测试管理等功能。同时,本文还介绍了其他软件测试相关工具,如功能自动化工具和性能自动化工具,以及白盒测试工具的使用。通过本文的阅读,读者可以了解禅道的基本使用方法和优势,从而更好地进行测试管理工作。 ... [详细]
author-avatar
潘PanPanPq
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有