【WebAPI No.3】API的访问控制IdentityServer4

本文涉及的产品
访问控制,不限时长
简介: 介绍: IdentityServer是一个OpenID Connect提供者 - 它实现了OpenID Connect和OAuth 2.0协议。是一种向客户发放安全令牌的软件。 官网给出的功能解释是: 保护您的资源 使用本地帐户存储或通过外部身份提供商对用户进行身份验证 提供会话管理和单...

介绍:

IdentityServer是一个OpenID Connect提供者 - 它实现了OpenID Connect和OAuth 2.0协议。是一种向客户发放安全令牌的软件。

官网给出的功能解释是:

  • 保护您的资源
  • 使用本地帐户存储或通过外部身份提供商对用户进行身份验证
  • 提供会话管理和单点登录
  • 管理和认证客户
  • 向客户发布身份和访问令牌
  • 验证令牌

IdentityServe4的四种模式:

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

以下是IdentityServer的一个大致流程图:

 

注册IdentityServe4认证服务器:

先在asp.net core我们选中空模版。因为本身写的业务也不多,只是为了做token的认证处理,所有建这个做测试比较方便。

创建代码示例:

什么时候都不要忘记添加引用哦:

NuGet命令行:Install-Package IdentityServer4

当然你也可以这样:

然后创建config.cs类来处理我们的一些业务:

 //定义范围
        #region 定义要保护的资源(webapi)
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("FirstAPI", "API接口安全测试")
            };
        }
        #endregion

        #region 定义可访问客户端
        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    //客户端id自定义
                    ClientId = "YbfTest",

                    AllowedGrantTypes = GrantTypes.ClientCredentials, ////设置模式,客户端模式

                    // 加密验证
                    ClientSecrets = new List<Secret>
                    {
                        new Secret("secret".Sha256())
                    },

                    // client可以访问的范围,在GetScopes方法定义的名字。
                    AllowedScopes = new List<string>
                    {
                        "FirstAPI"
                    }
                }
            };
        } 
        #endregion
View Code

以上就是一个基本的处理类了。然后我们开始在Startup.cs 配置IdentityServer4

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
                 .AddDeveloperSigningCredential()
                 .AddInMemoryApiResources(Config.GetApiResources())  //配置资源               
                 .AddInMemoryClients(Config.GetClients());//配置客户端
        }
View Code
 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //将IddiTyServer添加到管道中。
            app.UseIdentityServer();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
View Code

这样就可以启动项目了,确认项目启动完成后,还要确认服务是否开启成功:在地址后增加地址:/.well-known/openid-configuration 例如:

出现以上结果就是启动成功了。

当然你也可以使用postMan测试工具测试:

需要输入

  • grant_type为客户端授权client_credentials,
  • client_idConfig中配置的ClientId
  • Client_Secret为Config中配置的Secret

例如:

 创建webAPI资源服务器

这个比较简单了,首先创建一个简单的webapi程序即可。

还是老规矩咯iuput,什么时候都不要忘记引用:

通过nuget添加即可:IdentityServer4.AccessTokenValidation

然后点击确定安装就可以了。

主要认证注册服务:

在Startup类里面的ConfigureServices方法里面添加注册

        public void ConfigureServices(IServiceCollection services)
        {
            //注册IdentityServer 
            services.AddAuthentication(config => {
                config.DefaultScheme = "Bearer"; //这个是access_token的类型,获取access_token的时候返回参数中的token_type一致
            }).AddIdentityServerAuthentication(option => {
                option.ApiName = "FirstAPI"; //资源名称,认证服务注册的资源列表名称一致,
                option.Authority = "http://127.0.0.1:5000"; //认证服务的url
                option.RequireHttpsMetadata = false; //是否启用https

            });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

然后在在Startup的Configure方法里配置Authentication中间件:

           //配置Authentication中间件
            app.UseAuthentication();

然后添加一个控制器进行验证测试:

我这里写了一个获取value值简单检测一下。

 // GET api/values
        [HttpGet]
        [Authorize]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }

这里注意要添加[Authorize]特性。用来做验证是否有权限的。没有的话,以上做的没有意义。需要引用命名空间:using Microsoft.AspNetCore.Authorization;

看一下正确的请求结果:

如果不传token值请求:

 

 

注意这里就会返回401的未授权状态。 

创建Client(客户端)

上面我们使用的是postman请求的以演示程序是否创建成功,这里我们假设一个用户的使用客户端,这里我们创建一个控制台来模拟一下真实的小场景。

既然是控制台就没什么好说的直接上代码main函数:

Task.Run(async () =>
            {
                //从元数据中发现终结点,查找IdentityServer
                var disco = await DiscoveryClient.GetAsync("http://127.0.0.1:5000");
                if (disco.IsError)
                {
                    Console.WriteLine(disco.Error);
                    return;
                }

                //向IdentityServer请求令牌
                var tokenClient = new TokenClient(disco.TokenEndpoint, "YbfTest", "YbfTest123");//请求的客户资源
                var tokenResponse = await tokenClient.RequestClientCredentialsAsync("FirstAPI");//运行的范围

                if (tokenResponse.IsError)
                {
                    Console.WriteLine(tokenResponse.Error);
                    return;
                }

                Console.WriteLine(tokenResponse.Json);

                //访问Api
                var client = new HttpClient();
                //把令牌添加进请求
                //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken);
                //client.SetBearerToken(tokenResponse.AccessToken);
                client.SetToken("Bearer", tokenResponse.AccessToken);

                var response = await client.GetAsync("http://localhost:42033/api/values");
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.StatusCode);
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(JArray.Parse(content));
                }
            });

            Console.ReadLine();
View Code

这里主要介绍一下请求资源时添加令牌主要有三种形式,我都在代码给出,根据api资源的注册形式选择适合的。api的注册我也写了两种形式。主要的区别就是token前面的Bearer,如果想写成自定义的和默认成Bearer就是这里的区分。

自定义就要使用:

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken);

如果全局默认的形式就不比每次请求都要添加所以可以写成:

client.SetBearerToken(tokenResponse.AccessToken);

运行项目之后出现成功界面:

 

 传送门

WebApi系列文章目录介绍

作者:YanBigFeg —— 颜秉锋

出处:http://www.cnblogs.com/yanbigfeg

本文版权归作者和博客园共有,欢迎转载,转载请标明出处。如果您觉得本篇博文对您有所收获,觉得小弟还算用心,请点击右下角的 [推荐],谢谢!

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
目录
相关文章
|
2月前
|
XML 开发框架 .NET
ASP.NET Web Api 如何使用 Swagger 管理 API
ASP.NET Web Api 如何使用 Swagger 管理 API
|
2月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
|
5月前
|
Web App开发 前端开发 测试技术
【Web API系列】使用异步剪贴板API(async clipboard)的图像的编程复制和粘贴
【Web API系列】使用异步剪贴板API(async clipboard)的图像的编程复制和粘贴
162 1
|
JavaScript 前端开发 API
什么是 Web API 中的 background fetch API
什么是 Web API 中的 background fetch API
|
JavaScript Java 程序员
API 与 Web API 以及 与Java Script 基础的关联
API 与 Web API 以及 与Java Script 基础的关联
80 0
|
Kubernetes Cloud Native API
带你读《云原生应用开发:Operator原理与实践》——2.3.1 Kubernetes API 访问控制
带你读《云原生应用开发:Operator原理与实践》——2.3.1 Kubernetes API 访问控制
|
测试技术 API
【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿。而这之前,程序之间通信效率的王者也许可以算得上是gRPC了。那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着比拼一下minimal api服务和gRPC服务在通信上的效率。
436 0
【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
|
XML JavaScript 程序员
什么是API和Web API
什么是API和Web API
242 0
|
Web App开发 XML 开发框架
WebAPI学习(一)——创建Web API程序
WebAPI学习(一)——创建Web API程序
286 0
|
JavaScript Java 程序员
JS 的 API 与Web API 的关系
JS 的 API 与Web API 的关系
JS 的 API 与Web API 的关系