天天看点

AspNetCore打造一个“最安全”的api接口

Authentication,Authorization

如果公司交给你一个任务让你写一个api接口,那么我们应该如何设计这个api接口来保证这个接口是对外看起来“高大上”,“羡慕崇拜”,并且使用起来和普通api接口无感,并且可以完美接入aspnetcore的认证授权体系呢,而不是自定义签名来进行自定义过滤器实现呢(虽然也可以但是并不是最完美的),如何让小白羡慕一眼就知道你是老鸟。

接下来我将给大家分享你不知道的自定义认证授体系。

我相信这可能是你面对aspnetcore下一个无论如何都要跨过去的坎,也是很多老鸟不熟悉的未知领域(很多人说能用就行,那么你可以直接右上角或者左上角)

在不考虑性能的影响下我们选择非对称加密可以选择sm或者rsa加密,这边我们选择rsa2048位pkcs8密钥来进行,http传输可以分为两个一个是request一个是response两个交互模式。

安全的交互方式在不使用https的前提下那么就是我把明文信息加密并且签名后给你,你收到后自己解密然后把你响应给我的明文信息加密后签名在回给我,这样就可以保证数据交互的安全性,

非对称加密一般拥有两个密钥,一个被称作为公钥,一个被称作为私钥,公钥是可以公开的哪怕放到互联网上也是没关系的,私钥是自己保存的,一般而言永远不会用到自己的私钥。

私钥签名的结果只能被对应的公钥校验成功,公钥加密的数据只能被对应的私钥解密

假设我们现在是两个系统间的交互,系统A,系统B。系统A有一对rsa密钥对我们称之为公钥APubKey,私钥APriKey,系统B有一对rsa密钥我们称之为公钥BPubKey,私钥BPriKey。

私钥是每个系统生成后自己内部保存的,私钥的作用就是告诉发送方收到的人一定是我,公钥的作用就是告诉接收到是不是我发送的,基于这两条定理我们来设计程序,

首先我们系统A调用系统B的Api1接口假设我们传递一个hello,然后系统B会回复一个world。那么我们如何设计才可以保证安全呢。首先系统A发送消息如何让系统B知道是系统A发过来的而不是别的中间人共计呢。这里我们需要用到签名,就是说系统A用APriKey进行对hello的加密后那么如果发过去的数据如果签名是x内容是hello,系统B收到了就会对hello进行签名的校验,如果校验出来的结果是用私钥加密的那么你用哪个公钥进行的前面校验就可以保证系统是由哪个系统发送的。用APriKey进行签名的数据只有用APubKey进行签名校验才能通过,所以系统B就可以确保是有系统A发送的而不是别的系统,那么我们到现在还是传送的明文信息,所以我们还需要将数据进行加密,加密一般我们选择的是接收方的公钥,因为只有用接收方的公钥加密后才能由接收方的私钥解密出来

AspNetCore打造一个“最安全”的api接口

首先我们创建一个简单的aspnetcore的webapi项目

AspNetCore打造一个“最安全”的api接口

创建一个配置选项用来存储私钥公钥

创建一个Scheme选项类

定义一个常量

创建我们的认证处理器 <code>AuthSecurityRsaAuthenticationHandler</code>

第三步我们添加扩展方法

添加返回结果加密解密 SafeResponseMiddleware

新增基础基类来实现认证

到这个时候我们的接口已经差不多写完了,只是适配了微软的框架,但是还是不能happy coding,接下来我们要实现模型的解析和校验

首先我们要确保微软是如何通过request body的字符串到model的绑定的,通过源码解析我们可以发现aspnetcore是通过<code>IModelBinder</code>

首先实现模型绑定

添加attribute的特性解析

添加测试dto

创建模型控制器

添加异常全局捕获

添加模型校验

startup配置

到此为止我们服务端的所有api接口和配置都已经完成了接下来我们通过编写客户端接口和生成rsa密钥对就可以开始使用api了

下载地址openssl

AspNetCore打造一个“最安全”的api接口

双击

AspNetCore打造一个“最安全”的api接口

输入创建命令

AspNetCore打造一个“最安全”的api接口

公钥和私钥不是xml格式的C#使用rsa需要xml格式的秘钥,所以先转换对应的秘钥

首先nuget下载公钥私钥转换工具

AspNetCore打造一个“最安全”的api接口
AspNetCore打造一个“最安全”的api接口

依次启动两个项目就可以看到我们调用成功了,

完美接入aspnetcore认证系统和权限系统(后续会出一篇如何设计权限)

系统交互采用双向加密和签名认证

完美接入模型校验

完美处理响应结果

注意本项目仅仅只是是一个学习demo,而且根据实践得出的结论rsa加密仅仅是满足了最最最安全的api这个条件,但是性能上而言会随着body的变大性能急剧下降,所以并不是一个很好的抉择当然可以用在双方交互的时候设置秘钥提供api接口,实际情况下可以选择使用对称加密比如:AES或者DES进行body体的加密解密,但是在签名方面完全没问题可以选择rsa,本次使用的是rsa2(rsa 2048位的秘钥)秘钥位数越大加密等级越高但是解密性能越低

当然你可以直接上https,本文章也不是说一定要双向处理更多的是分享如何接入aspnetcore的认证体系中和模型校验,而不用帖一大堆的attribute

AspNetCoreSafeApi

Gitee Star 助力dotnet 生态 Github Star

博客

QQ群:771630778

个人QQ:326308290(欢迎技术支持提供您宝贵的意见)

个人邮箱:[email protected]

继续阅读