IdentityServer4是什么?

IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现。

OpenID Connect 和 OAuth2.0是什么

OpenID Connect:

OpenID Connect由OpenID基金会于2014年发布的一个开放标准, 是建立在OAuth 2.0协议上的一个简单的身份标识层, OpenID Connect 兼容 OAuth 2.0. 实现身份认证(Authentication)
参考资料:https://openid.net/connect/
OpenID Connect文档:https://openid.net/specs/openid-connect-discovery-1_0.html

OAuth2.0:

OAuth2.0是一个开放的工业标准的授权协议(Authorization),它允许用户授权让第三方应用直接访问用户在某一个服务中的特定资源,但不提供给第三方账号及密码信息
参考资料:https://www.cnblogs.com/xiandnc/p/9763121.html
OAuth2.0 文档:https://tools.ietf.org/html/rfc6749#page-73

Authentication 和 Authorization的区别

authentication: n. 证明;鉴定;证实
authorization: n. 授权,认可;批准,委任

前者是身份识别,鉴别你是谁;后者是授权许可,告诉你可以做什么。
举个例子:你吭哧吭哧写了一天的代码,急于回家吃上一口媳妇做的热饭。当你走到小区门口的时候你需要刷小区的门禁卡才能进入到小区里面,然后再找到你家在哪一栋楼,几单元几号,然后掏出钥匙开门才能回到家。在这个过程中刷小区的门禁就是认证你是这个小区的人,拿你家的钥匙开门就是授权的过程,如果你的认证不通过,那就不存在授权。

OAuth2.0的原理

我们先来了解一下OAuth2.0中的几个关键概念:

资源所有者(Resource Owner):

  一个能够访问受保护资源的实体。当资源所有者是一个人时,它被称为终端用户

资源服务器(Resource Server):

  托管受保护资源的服务器,能够使用访问令牌接受和响应受保护的资源请求

客户端(Client):

  代表资源所有者和其授权的应用程序来保护资源请求。术语客户端并不意味着任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行)

授权服务器(Authorization Server):

  在成功验证资源所有者并获得授权之后,服务器向客户端发出访问令牌。(授权服务器是用来管理Resource Owner,Resource Server,Client的中间人)

场景:小李想要打印(美图快印)自己三年来发布在新浪微博相册中和女朋友的照片,有没有什么方法他既不告诉工作人员自己的新浪微博用账号和密码又能够方便快捷的把照片给到美图快印呢?(排除存U盘这种手工操作)

Authorization Server和Resource Server可以使独立的服务提供商,也可以是在一起的,比如例子中新浪微博既作授权服务器也用来存储用户的图片资源。我们可以看到OAuth2解决的问题是:通过Authorization Server可以提供一个访问的凭据(token)给client(美图快印的工作人员),使得client可以在不知道Resource Owner以及Resource Server的用户名和密码的情况下访问到Resource Owner受保护的资源,它是一个完美的中间人。  

OAuth2.0详细内容请参考:https://www.cnblogs.com/xiandnc/p/9763121.html

IdentityServer4能做什么

用户认证服务

  基于OpenID Connect实现的独立的认证服务实现对多平台(web, native, mobile, services)的集中认证

API访问授权

  为各种类型的客户机颁发api访问令牌,例如服务器到服务器、web应用程序、spa和native/mobile程序

联合身份认证

  支持外部身份提供者,如Azure Active Directory、Google、Facebook等

定制化的实现

  IdentityServer4的许多方面可以定制以满足您的需要,因为它是一个框架,而不是SaaS服务,所以可以通过编写代码来调整实现,以适应不同的场景

成熟的开原方案

  使用许可的Apache2开源协议,允许在其之上构建商业产品,也作为.NET基金会支持的项目 (https://dotnetfoundation.org/projects?type=project&ps=10&pn=6

提供免费的商业支持

  官方可以对使用者提供部分的免费商业支持

IdentityServer4定义的基本术语

IdentityServer

  身份认证服务器是一个实现了OpenID Connect和OAuth 2.0协议的身份提供者,它负责向客户端发布安全令牌

User

  使用注册客户端访问资源的用户

Client

客户端从标识服务器请求令牌,要么用于认证用户(请求身份令牌),要么用于访问资源(请求访问令牌)
        客户端必须首先在身份服务器上注册,然后才能请求令牌
       这里的客户端可以是web应用程序、native mobile, desktop applications, SPA 等程序

Resource
  资源是你想要用身份认证服务器保护的东西,如:用户的身份数据或api
  每个资源都有一个惟一的名称,客户端使用这个名称来指定他们想要访问的资源
  关于用户的身份数据标识(也称为claim),例如姓名或电子邮件地址

Identity Token
  身份令牌代表身份验证过程的结果

Access Token
  访问令牌授权客户端以允许访问哪些API资源,访问令牌包含客户端和用户的信息

IdentityServer4的简单示例

我们先来看一个简单的例子,我们有三个API ,Order, Product, Inventory,我们利用IdentityServer4来实现对着三个API的认证和授权。首先我们需要一个实现认证和授权的服务,然后外部要想访问我们的API就必须通过统一的认证和授权服务的任何才可以,否则就是返回401: UnAuthorized ,未经授权的访问。我们既可以将身份信息存储到内存中,也可以将其持久化到数据库中,此处我们使用内存模式快速的演示实现(示例代码中也支持存储到DB中,使用SqlLite + EF Core)

首先我们需要安装IdentityServer4的Nuget包,然后在ConfigureServices方法中添加如下代码来初始化需要保护的API资源信息,代码如下:

 

public void ConfigureServices(IServiceCollection services)
{
// config data in memory
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(InitMemoryData.GetApiResources())
.AddInMemoryClients(InitMemoryData.GetClients())
.AddTestUsers(InitMemoryData.GetUsers()); // config in DB
//services.AddDbContext<IdentityServerDbContext>(options =>
// options.UseSqlite(sqliteConnection));
}

 InitMemoryData 中的配置信息如下:

 // scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("inventoryapi", "this is inventory api"),
new ApiResource("orderapi", "this is order api"),
new ApiResource("productapi", "this is product api")
};
} // clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
new Client
{
ClientId = "inventory",
AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets =
{
new Secret("inventorysecret".Sha256())
}, AllowedScopes = { "inventoryapi" }
},
new Client
{
ClientId = "order",
AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets =
{
new Secret("ordersecret".Sha256())
}, AllowedScopes = { "orderapi" }
},
new Client
{
ClientId = "product",
AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets =
{
new Secret("productsecret".Sha256())
}, AllowedScopes = { "productapi" }
}
};
}

我们给IdentityServer4设置启动端口5000,认证服务的地址就是:http://localhost:5000 

然后认证Server端的代码就好了,接下来我们需要在API添加授权服务的配置,配置都很类似,我们以OrderAPI为例: 

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters(); services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "orderapi";
});
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMvc();
}

这里我们配置的Authority地址就是认证授权的地址,AddAuthentication中的Bearer是Jwt Token的一种,具体可参考文章:https://www.cnblogs.com/Leo_wl/p/7792046.html

在controller中添加简单代码来返回API的信息:

[Route("[controller]")]
[Authorize]
public class OrderController : ControllerBase
{
// GET api/order
[HttpGet]
public IActionResult Get()
{
var userIdentitys = from c in User.Claims
select new UserIdentity
{
Type = c.Type,
Value = c.Value
};
var result = new UserIdentityModel()
{
Description = "Access user order api successfully",
UserIdentitys = userIdentitys.ToList()
}; return new JsonResult(result);
}
}

设置当前API的端口为:5002

Product和Inventory中的配置和这个类似,端口信息以此设置为5001,5003,一切就绪,让我们来测试一下结果:

启动IdentotyServer,以及三个API,我们使用Postman来请求api,下面站点就是IdentityServer的页面了:

接着我们来直接访问OrderAPI就会发现返回 401 ,这说明目前我们的API已经受保护了,没有认证服务颁发的token,是直接访问不了的。

我们输入地址:http://localhost:5000/.well-known/openid-configuration 可以查看我们当前认证授权服务的配置信息:

现在还差一步就可以访问我们的OrderAPI了,那就是:客户端传入必要的信息给认证服务,生成一定格式的token,然后携带着这个token来访问我们的服务 

传入的三个参数分别是grant_type , client_sercret, client_id这几个参数分别代表了我们申请token时的授权方式是客户端授权,密匙,clientid信息。我们在前面介绍过IdentityServer4是对OAuth2.0的实现,所以具体参数的含义请参考之前OAuth2.0文章中的详细介绍

https://www.cnblogs.com/xiandnc/p/9763121.html

此时我们可以看到认证服务给我们返回了有效token,指定过期时间3600s ,token的类型是Bearer,然后我们再携带这这个token去访问服务试试看:

我们可以看到此时API 返回了我们期待的正确结果,如果在1小时后再携带着这个token去访问API就会提示token已过期,需要重新生成才能够继续访问。看完这个例子是不是很简单,很清爽呢

例子参考代码:https://github.com/KenWang007/IdentityServer4Demo

基于IdentityServer4 实现.NET Core的认证授权的更多相关文章

  1. 一款基于.NET Core的认证授权解决方案-葫芦藤1.0开源啦

    背景 18年公司准备在技术上进行转型,而公司技术团队是互相独立的,新技术的推动阻力很大.我们需要找到一个切入点.公司的项目很多,而各个系统之间又不互通,导致每套系统都有一套登录体系,给员工和客户都带来 ...

  2. ASP.NET Core JWT认证授权介绍

    using JWTWebApi.Models; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetC ...

  3. 一看就懂的IdentityServer4认证授权设计方案

    查阅了大多数相关资料,总结设计一个IdentityServer4认证授权方案,我们先看理论,后设计方案. 1.快速理解认证授权 我们先看一下网站发起QQ认证授权,授权通过后获取用户头像,昵称的流程. ...

  4. 基于.NetCore3.1系列 ——认证授权方案之Swagger加锁

    一.前言 在之前的使用Swagger做Api文档中,我们已经使用Swagger进行开发接口文档,以及更加方便的使用.这一转换,让更多的接口可以以通俗易懂的方式展现给开发人员.而在后续的内容中,为了对a ...

  5. 【ASP.NET Core学习】使用JWT认证授权

    概述 认证授权是很多系统的基本功能 , 在以前PC的时代 , 通常是基于cookies-session这样的方式实现认证授权 , 在那个时候通常系统的用户量都不会很大, 所以这种方式也一直很好运行, ...

  6. .net core gRPC与IdentityServer4集成认证授权

    前言 随着.net core3.0的正式发布,gRPC服务被集成到了VS2019.本文主要演示如何对gRPC的服务进行认证授权. 分析 目前.net core使用最广的认证授权组件是基于OAuth2. ...

  7. asp.net core 使用identityServer4的密码模式来进行身份认证(2) 认证授权原理

    前言:本文将会结合asp.net core 认证源码来分析起认证的原理与流程.asp.net core版本2.2 对于大部分使用asp.net core开发的人来说. 下面这几行代码应该很熟悉了. s ...

  8. .Net Core权限认证基于Cookie的认证&授权.Scheme、Policy扩展

    在身份认证中,如果某个Action需要权限才能访问,最开始的想法就是,哪个Action需要权限才能访问,我们写个特性标注到上面即可,[TypeFilter(typeof(CustomAuthorize ...

  9. .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

    介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还 ...

随机推荐

  1. APIO2017总结

    T1爆零,T2四分,实力滚粗,OI再见. 四年亚太,回到起点,辣鸡捆绑,毁我青春.

  2. VB使用API进行RC4加密解密(MD5密钥)

    根据网络资料整改,来源未知,已调试通过. Option Explicit Private Declare Function CryptAcquireContext Lib "advapi32 ...

  3. python操作git

    GitPython 是一个用于操作 Git 版本库的 python 包,它提供了一系列的对象模型(库 - Repo.树 - Tree.提交 - Commit等),用于操作版本库中的相应对象. 模块安装 ...

  4. Linux用命令启动程序(eclipse、IDEA等)

    打开根目录用管理员权限打开HOME 找到下图截图中的框选出的文件 用文本编辑器打开后 在文件末尾添加所需要打开的应用文件所在的目录 这里以本人的IDEA和eclipse为例:

  5. 两层fragment嵌套时出现空白,(收藏别人的)

    完美解决 两层Fragment,内层空白 转载:http://blog.csdn.net/bingospunky/article/details/51352400 目录(?)[+] 前言 两层Frag ...

  6. APP测试工具与技术

    AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...

  7. 【DFS】求水洼的数目

    题目: 有一个大小为 N*M 的园子,雨后积起了水.八连通的积水被认为是连接在一起的.请求出园子里总共有多少水洼?(八连通指的是下图中相对 W 的*的部分) *** *W* *** 限制条件:N, M ...

  8. PHP 图片base64 互转

    <?php /* http://tool.css-js.com/base64.html 透明图片 <img src="data:image/jpg;base64,iVBORw0K ...

  9. [Swift]LeetCode164. 最大间距 | Maximum Gap

    Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...

  10. [Swift]LeetCode448. 找到所有数组中消失的数字 | Find All Numbers Disappeared in an Array

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...