asp.Net   发布时间:2022-04-07  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了IdentityServer4 知多少大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/12f9b8afb8f9ac301b10dd50cba6fb79.png">

现在的应用开发层出不穷,基于浏览器的网页应用,基于微信的公众号、小程序,基于IOS、Android的App,基于Windows系统的桌面应用和UWP应用等等,这么多种类的应用,就给应用的开发带来的挑战,我们除了分别实现各个应用外,我们还要虑各个应用之间的交互,通用模块的提炼,其中身份的认证和授权就是每个应用必不可少的的一部分。而现在的互联网,对于信息安全要求又十分苛刻,所以一套统一的身份认证和授权就至关重要。

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/9461aaa21494e4f534db2f25ddc67196.png" >

下面我们就来介绍一下相关概念,并梳理下如何集成IdentityServer4。 也可浏览自行整理的快速了解。

IdentityServer4 知多少

简而言之:OpenId用于身份认证(Authentication)

简而言之:OAuth2.0 用于授权(Authorization)。关于OAuth2.0也可参考我的另一篇博文

简而言之:OpenId Connect = OIDC = Authentication + Authorization + OAuth2.0

比如,Facebook、Google、QQ、微博都是比较知名的OpenId Connect提供商。

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/21eac6c75063f3fa088f85720117ade5.png">

了解完OpenId Connect和OAuth2.0的基本概念,我们再来梳理下涉及到的相关术语:

  1. User:用户
  2. Client:客户端
  3. resources:Identity Data(身份数据)、Apis
  4. Identity Server:认证授权服务器
  5. Token:Access Token(访问令牌)和 Identity Token(身份令牌)

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/8e9aa6cf4dae864d367fe9466e9686d8.png">

http身份验证流程">4.1. http身份验证流程

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/0ce1bc73cd32889833f220fd80647399.png" >

Bearer认证(也叫做令牌认证)是一种http认证方案,其中包含的安全令牌的叫做Bearer Token。因此Bearer认证的核心是Token。那如何确保Token的安全是重中之重。一种方式是使用https,另一种方式就是对Token进行加密签名。而JWT就是一种比较流行的Token编码方式。

JWT有三部分组成:

..

  1. Header:由algtyp组成,alg是algorithm的缩写,typ是type的缩写,指定token的类型。该部分使用Base64Url编码。
  2. Payload:主要用来存储信息,包含各种声明,同样该部分也由BaseURL编码。
  3. Signature:签名,使用服务器端的密钥进行签名。以确保Token未被篡改。
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),secret)

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

  1. Implicit:简化模式;直接通过浏览器的链接跳转申请令牌。
  2. Client Credentials:客户端凭证模式;该方法通常用于服务器之间的通讯;该模式仅发生在Client与Identity Server之间。
  3. resource owner password Credentials:密码模式
  4. Authorization Code:授权码模式;

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/e04987578e66345371be5363ff677645.png" >

客户端凭证模式,是最简单的授权模式,因为授权的流程仅发生在Client与Identity Server之间。

该模式的适用场景为服务器与服务器之间的通信。比如对于一个电子商务网站,将订单和物流系统分拆为两个服务分别部署。订单系统需要访问物流系统进行物流信息的跟踪,物流系统需要访问订单系统的快递单号信息进行物流信息的定时刷新。而这两个系统之间服务的授权就可以通过这种模式来实现。

resource-owner-password-credentials">5.2. resource owner password Credentials

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/4d92445ecc53e9f7f6e765818a2897e2.png" >

resource owner其实就是User,所以可以直译为用户名密码模式。密码模式相较于客户端凭证模式,多了一个参与者,就是User。通过User的用户名和密码向Identity Server申请访问令牌。这种模式下要求客户端不得储存密码。但我们并不能确保客户端是否储存了密码,所以该模式仅适用于受信任的客户端。否则会发生密码泄露的危险。该模式不推荐使用

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/301cf22f1f939c6c5f6037eda6f649ef.png" >

授权码模式是一种混合模式,是目前功能最完整、流程最严密的授权模式。它主要分为两大步骤:认证和授权。 其流程为:

  1. 用户访问客户端,客户端将用户导向Identity Server。
  2. 用户填写凭证信息向客户端授权,认证服务器根据客户端指定的重定向URI,并返回一个【Authorization Code】给客户端。
  3. 客户端根据【Authorization Code】向Identity Server申请【Access Token】

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/12a017d3398729ccd97d56878a0a0785.png" >

简化模式是相对于授权码模式而言的。其不再需要【Client】的参与,所有的认证和授权都是通过浏览器来完成的。

title="IdentityServer4 知多少" alt="IdentityServer4 知多少" src="https://cn.js-code.com/res/2019/02-08/23/0b4140e7739c19af7e73359e94d5fc39.png" >

通过以上知识点的梳理,我们对OpenId Connect 和OAuth2.0的一些相关概念有了大致认识。而IdentityServer4是为ASP.NET CORE量身定制的实现了OpenId Connect和OAuth2.0协议的认证授权中间件。 所以自然而然我们对IdentityServer4有了基础的认识。下面就来介绍如何集成IdentityServer4。其主要分为三步:

  1. IdentityServer如何配置和启用IdentityServer中间件
  2. resources如何配置和启用认证授权中间件
  3. Client如何认证和授权

作为一个独立的Identity Server,它必须知道哪些资源需要保护,必须知道哪些客户端能够允许访问,这是配置的基础。 所以IdentityServer中间件的配置的核心就是:

  1. 配置受保护的资源列表
  2. 配置允许验证的Client
public class Startup
{
    public void Configureservices(IserviceCollection services)
    {
        services.AddMvc();
        // configure identity server with in-memory stores,keys,clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
             //配置身份资源
            .AddInMemoryIdentityresources(Config.GetIdentityresources())
              //配置API资源
            .AddInMemoryApiresources(Config.GetApiresources())
             //预置允许验证的Client
            .AddInMemoryClients(Config.GetClients())
            .AddTestusers(Config.GetUsers());
        services.AddAuthentication()
              //添加Google第三方身份认证服务(按需添加)
            .AddGoogle("Google",options =>
            {
                options.SignInscheR_241_11845@e = IdentityServerConstants.ExternalCookieAuthenticationscheR_241_11845@e;
                options.CLIENtId = "434483408261-55tc8n0cs4ff1fe21ea8df2o443v2iuc.apps.googleusercontent.com";
                options.CLIENtSecret = "3gcoTrEDPPJ0ukn_aYYT6PWo";
            })
            //如果当前IdentityServer不提供身份认证服务,还可以添加其他身份认证服                务提供商
            .AddopenIdConnect("oidc","OpenID Connect",options =>
            {
                options.SignInscheR_241_11845@e = IdentityServerConstants.ExternalCookieAuthenticationscheR_241_11845@e;
                options.SignOutscheR_241_11845@e = IdentityServerConstants.SignoutscheR_241_11845@e;
                options.Authority = "https://demo.identityserver.io/";
                options.CLIENtId = "implicit";
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",RoleClaimType = "role"
                };
            });
    }
    public void Configure(IApplicationBuilder app,IHosTingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        //添加IdentityServer中间件到Pipeline
        app.UsEIDentityServer();
        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();
    }

配置完,添加IdentityServer到Pipeline即可。

如果要支持第三方登录服务或自己实现的OpenId Connect服务,则需要额外配置下身份认证中间件。

resources的保护配置">6.2. resources的保护配置

配置完Identity Server,接下来我们该思如何来保护resources,以及如何将所有的认证和授权请求导流到Identity Server呢? 在此之前,我们还是要梳理下Client访问resources的请求顺序:

  1. Client请求资源,资源如果需要进行身份认证和授权,则将请求导流到Identity Server。
  2. Identity Server根据Client配置的授权类型,返回【Token】。
  3. Client要能够验证【Token】的正确性。

所以针对要保护的资源,我们需要以下配置:

  1. 指定资源是否需要保护;
  2. 指定IdentityServer用来进行认证和授权跳转;
  3. Client携带【Token】请求资源。
  4. 受保护的资源服务器要能够验证【Token】的正确性。

代码示例:

//使用[Authorize]特性,来显式指定受保护的资源
[Route("[controller]")]
[Authorize]
public class IdentityController : ControllerBase
{
    [httpGet]
    public IActionResult Get()
    {
        return new JsonResult(from c in User.Claims SELEct new { c.Type,c.Value });
    }
}
public class Startup
{
    public void Configureservices(IserviceCollection services)
    {
        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();
        //指定认证方案
        services.AddAuthentication("Bearer")
              //添加Token验证服务到DI
            .AddIdentityServerAuthentication(options =>
            {
                //指定授权地址
                options.Authority = "http://localhost:5000";
                options.requirehttpsMetadata = false;
                options.ApiName = "api1";
            });
    }
    public void Configure(IApplicationBuilder app)
    {
        //添加认证中间件到Pipeline
        app.UseAuthentication();
        app.UseMvc();
    }
}

资源和认证服务器都配置完毕,接下来客户端就可以直接访问了。 如果针对控制台客户端应用,三步走就可以访问Api:

  1. 使用DiscoverClient发现Token Endpoint
  2. 使用TokenClient请求Access Token
  3. 使用httpClient访问Api 代码示例如下:
// discover endpoints from metadata
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
// request token(使用的是ClientCredentials授权类型)
var tokenClient = new TokenClient(disco.TokenEndpoint,"client","secret");
var tokenResponse = await tokenClient.requestClientCredentialsAsync("api1")
if (tokenResponse.IsError)
{
    Console.WriteLine(tokenResponse.Error);
    return;
}
Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");
// call api
var client = new httpClient();
client.SetBearerToken(tokenResponse.AccessToken);

如果针对ASP.NET Web控制台客户端,我们先来回答一个问题:

  1. 如果Web应用是否需要登录?
  2. 如果需要登录,就需要进行身份认证。
  3. 身份认证成功后,也就需要会话状态的维持。

回答完上面的问题,我们也就梳理出了配置要点:

  1. 添加身份认证中间件
  2. 启用Cookie进行会话保持
  3. 添加OIDC,使用我们自己定义的IdentityServer提供的认证服务
public void Configureservices(IserviceCollection services)
{
    services.AddMvc();
    JwtSecurityTokenHandler.DefaulTinboundClaimTypeMap.Clear();
    services.AddAuthentication(options =>
        {
            options.DefaultscheR_241_11845@e = "Cookies";
            options.DefaultChALLENgescheR_241_11845@e = "oidc";
        })
        .AddCookie("Cookies")
        .AddopenIdConnect("oidc",options =>
        {
            options.SignInscheR_241_11845@e = "Cookies";
            options.Authority = "http://localhost:5000";
            options.requirehttpsMetadata = false;
            options.CLIENtId = "mvc";
            options.SaveTokens = true;
        });
}
public void Configure(IApplicationBuilder app,IHosTingEnvironment env
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseAuthentication();
    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

本文通过介绍IdentityServer4涉及到的术语和相关概念,再结合官方实例,梳理了集成IdentityServer4的大致思路。而关于如何与ASP.NET Identity、EF Core集成,本文并未涉及,详参官方文档。

大佬总结

以上是大佬教程为你收集整理的IdentityServer4 知多少全部内容,希望文章能够帮你解决IdentityServer4 知多少所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

标签: