IdentityServer4实现OAuth2.0四种模式之客户端模式

一,准备内容
IdentityServer4 是Asp.net core的一个中间件,用于添加符合OpenId Connect和OAuth2.0规范的终端到Asp.net Core应用。在这里简单介绍一下Openid和OAuth2.0。

OpenId:用户身份认证(Authentication )。当用户(End User)在微信、Google等OpenId提供者(OpenID Provider)平台注册账户时会产生一个身份标识,这个身份标识就是OpenId,当用户登录第三方应用(Relying Part)时如果Relying Part支持OpenId登录,会生成一个带有重定向地址的Url跳至OpenId Provider平台登录界面,用户登录成功后,根据重定向地址带着OpenId跳回Relying Part,标识着用户身份认证成功,该用户在OpenId Provider平台有注册。Relying Part根据OpenId自动注册账户,至此身份认证结束。有时Relying Part需要从Openid Provider那获取该用户的更多信息或资源,OpenId Provider需要对Relying Part的请求进行授权管理,这时就用要到OAuth2.0。

OAuth2.0:用户访问授权(Authorization)。OAuth2.0是一个JWT(Json Web Token ,Json格式Web令牌)解决方案。其最终目的是给用户一个包含加密令牌的JSON字符串,这个令牌内包含授权信息,决定了该用户可以访问那些资源。OAuth2.0协议规定了4种取得令牌的方式,可以参考这篇文章OAuth2.0的四种方式。

Openid Connect:实际上就是将Openid与OAuth2.0结合起来,解决身份认证和身份授权的问题。

客户端模式只对客户端进行授权,不涉及到用户信息。如果你的api需要提供到第三方应用,第三方应用自己做用户授权,不需要用到你的用户资源,就可以用客户端模式,只对客户端进行授权访问api资源。

二,创建Asp.net Core 项目
微软提供了一些针对IdentityServer4的项目模板,在命令行中输入” dotnet new -i IdentityServer4.Templates“即可安装,安装好后可以看到当前已安装的项目模板,其中有一个"is4empty",其实就是一个asp.net core 应用装了IdentityServer4包。在命令行中输入:dotnet new is4empty -n Projectname 就会根据这个模板生成一个新项目。下图是我的项目,一个api客户端、一个mvc客户端,一个identityserver4服务端,其中Api客户端是受保护的Api资源,Mvc客户端是第三方客户端,用于访问被保护的Api客户端,可以看成是任意后端程序。

请添加图片描述

配置IdentityServer服务器,如果是用的is4empty模板创建的项目,已经有一些简单配置,后面我们慢慢深化

public void ConfigureServices(IServiceCollection services)

      {

          //添加IdentityServer

          var builder = services.AddIdentityServer()

              //身份信息授权资源

              .AddInMemoryIdentityResources(Config.GetIdentityResources())

              //API访问授权资源

              .AddInMemoryApiResources(Config.GetApis())

              //添加客户端

              .AddInMemoryClients(Config.GetClients());

          if (Environment.IsDevelopment())

          {

              builder.AddDeveloperSigningCredential();

          }

          else

          {

              throw new Exception("need to configure key material");

          }

      }

      public void Configure(IApplicationBuilder app)

      {

          if (Environment.IsDevelopment())

          {

              app.UseDeveloperExceptionPage();

          }

          //使用IdentityServer中间件

          app.UseIdentityServer();

      }

为了能更好的查看调试日志,使用窗口调试,可以在Properties/launchSettings.json中可以更改监听地址,默认为5000

请添加图片描述

启动项目后使用浏览器打开:http://localhost:5000/.well-known/openid-configuration。可以看到identityserver4的discover说明。

三,配置IdentityServer4
1,添加ApiResource:修改IdentityServer项目的Config类的GetClients方法,添加一个api资源(ApiResource)。每个被保护的API项目必需有对应一个ApiResource,一个ApiResource可以有被多个API标识,客户端请求令牌时根据ApiResource名称决定是否有权限访问这个API。

public static IEnumerable<ApiResource> GetApis()

     {

         return new ApiResource[] {

             //secretapi:标识名称,Secret Api:显示名称,可以自定义

             new ApiResource("secretapi","Secret Api")

         };

     }

2,添加客户端模式用户:定义好ApiResouce后,再来添加一个客户端,使得这个客户端可以访问secretapi这个资源。修改Config类中的GetClients方法,添加一个用户用于支持客户端模式的请求。

public static IEnumerable<Client> GetClients()

        {

            return new Client[] {

               

                new Client()

                {

                    //客户端Id

                     ClientId="apiClientCd",

                     //客户端密码

                     ClientSecrets={new Secret("apiSecret".Sha256()) },

                     //客户端授权类型,ClientCredentials:客户端凭证方式

                     AllowedGrantTypes=GrantTypes.ClientCredentials,

                     //允许访问的资源

                     AllowedScopes={

                        "secretapi"

                    }

                }

            };

        }

四,配置API客户端
1,配置API项目监听端口和调试方式

请添加图片描述
2,配置Api项目认证

IdentityApi.Startup.cs

public void ConfigureServices(IServiceCollection services)

        {

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddAuthentication("Bearer").AddJwtBearer(r => {

                //认证地址

                r.Authority = "http://localhost:5000";

                //权限标识

                r.Audience = "secretapi";

                //是否必需HTTPS

                r.RequireHttpsMetadata = false;

            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)

        {

            if (env.IsDevelopment())

            {

                app.UseDeveloperExceptionPage();

            }

            else

            {

                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

                app.UseHsts();

            }

            app.UseHttpsRedirection();

            //使用认证中间件

            app.UseAuthentication();

            app.UseMvcWithDefaultRoute();

        }

3,添加接口:新建一个空的Api控制器(IdentityController),在这个控制器中添加一个Api:GetUserClaims

[ApiController]

  public class IdentityController : ControllerBase

  {

      [HttpGet]

      [Route("api/identity")]

      [Microsoft.AspNetCore.Authorization.Authorize]

      public object GetUserClaims()

      {

          return User.Claims.Select(r => new { r.Type, r.Value });

      }

  }

这时GetUserClaims这个Api是访问不了的,用PostMan访问时返回401未认证状态

请添加图片描述

五,访问受保护的Api
要访问上面那个受保护的Api,分为2步,第一步从IdentityServer获取token,第二步把这个token使用Bearer authorization 方式添加到Http请求头。

1,在IdentityMvc项目访问受保护的Api

IdentityMvc项目安装一个Nuget包:IdentityModel,这个包对HttpClient对象有扩写,封装了一些IdentityServer的常用请求。修改IdentityServer的监听端口为5002,使用窗口调试。

在IdentityMvc的HomeController.cs新增一个控制器GetData

public async Task<IActionResult> GetData()

      {

          var client = new HttpClient();

          var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

          if (disco.IsError)

              return new JsonResult(new { err=disco.Error});

          var token= await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest() {

              //获取Token的地址

              Address = disco.TokenEndpoint,

              //客户端Id

              ClientId = "apiClientCd",

              //客户端密码

              ClientSecret = "apiSecret",

              //要访问的api资源

              Scope = "secretapi"

          });

          if (token.IsError)

              return new JsonResult(new { err = token.Error });

          client.SetBearerToken(token.AccessToken);

          string data = await client.GetStringAsync("https://localhost:5001/api/identity");

          JArray json = JArray.Parse(data);

          return new JsonResult(json);

      }


访问https://localhost:5002/home/getdata可以看到已经成功返回数据

请添加图片描述
2,使用原生HTTP请求访问受保护的Api

获取access_token:直接打开http://localhost:5000/.well-known/openid-configuration,找到token_endpoint节点

请添加图片描述
使用PostMan对该节点发送如下Post请求获取access_token

请添加图片描述
访问被保护的Api

由于使用的是Bearer认证机制,所以添加一个名为Authorization的Http请求头,请求头的内容是字符串“Bearer”+空格+获取到的Token:Bearer Token

请添加图片描述

转载于:
https://blog.csdn.net/xwnxwn/article/details/127597353

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值