【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

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

相关实践学习
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
目录
相关文章
|
11月前
|
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服务在通信上的效率。
366 0
【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
|
Web App开发 XML 开发框架
WebAPI学习(一)——创建Web API程序
WebAPI学习(一)——创建Web API程序
249 0
|
编解码 JavaScript 前端开发
Web API——Web API介绍
Web API——Web API介绍
179 0
Web API——Web API介绍
|
Shell API 数据安全/隐私保护
kubernetes API 访问控制在阿里云容器服务(ACK)上的实践
提起K8s API的访问控制,很多同学应该都会想到RBAC,这是K8s用来做权限控制的方法,但是K8s对API的访问控制却不止于此,今天我们就来简单介绍下K8s的访问控制以及ACK如何利用这套方法提供便捷的访问控制管理 访问控制简要说明 控制流程如上图所示,我们今天关注点在前两步,也就是图中的Au.
8544 0
|
.NET API 数据格式
Asp.Net Core WebAPI使用Swagger时API隐藏与分组
Asp.Net Core WebAPI使用Swagger时API隐藏与分组1、前言为什么我们要隐藏部分接口? 因为我们在用swagger代替接口的时候,难免有些接口会直观的暴露出来,比如我们结合Consul一起使用的时候,会将健康检查接口以及报警通知接口暴露出来,这些接口有时候会出于方便考虑,没有进行加密,这个时候我们就需要把接口隐藏起来,只有内部的开发者知道。
2664 0
|
.NET API 开发框架
从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller 版权声明:本文为博主原创文章,未经博主允许不得转载。
1218 0
|
XML JSON 中间件
【WebAPI No.4】Swagger实现API文档功能
介绍: Swagger也称为Open API,Swagger从API文档中手动完成工作,并提供一系列用于生成,可视化和维护API文档的解决方案。简单的说就是一款让你更好的书写API文档的框架。 我们为什么选择swagger,现在的网站开发结果越来越注重前后端的分离,比如以前的webFrom到现在的mvc模式都是为了这个前后端的分离。
1721 0
|
Web App开发 前端开发 .NET
【Web API系列教程】1.1 — ASP.NET Web API入门
前言 HTTP不仅仅服务于web页面,同时也是构建暴露服务和数据的API的强大平台。HTTP有着简单、灵活和无处不在的特点。
1139 0
|
15天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。