去中心化应用程序(DApp)的常见设计不仅依赖于以太坊区块链,还依赖于API层。在这种情况下,DApp通过用户的以太坊帐户与智能合约进行交互,并通过交换用户凭据而发布的JWT token与API层进行交互。

目标是使用以太坊帐户作为用户凭据来请求JWT Token。

最简单的方法可能是请求用户使用其他随机生成的数据在以太坊上进行交易,然后在发出JWT之前检查交易和随机数据。这种方法有几个副作用:

  • 1.用户必须进行交易并支付gas以进行简单的身份验证。
  • 2.用户必须等待12-120秒(基于耗费的gas)才能完成身份验证过程。
  • 3.每个用户的所有登录操作在以太坊区块链上变得不可公开。

这种方式不实用,并且有一些用户体验限制,我们需要一种方法让用户证明他拥有与他想要用来登录的帐户相关的私钥,而不是只(当然)要求私钥,而不管他是否进行交易。

解决方案

Metamask团队成员Dan Finlay的这篇文章向我启发了本教程。基本上,你的DApp可以提示用户使用他的私钥对短信进行签名。此签名操作不会生成交易,并且它由Metamask附加组件透明地处理(顺便说一句,你的帐户需要解锁)。签名后,帐户,消息和签名将发送到API Token endpoint。验证方法首先通过接受签名和明文消息作为输入的函数从签名中推断帐户(也称为公钥)。如果计算的以太坊地址等于用户提供的帐户,则为该帐户发出JWT Token。

请务必注意,整个身份验证流程不需要用户名/密码或OAuth外部服务。用于验证用户身份的机制与以太坊用于保证以太坊区块链安全性的机制相同。这要归功于Go ethereum(Geth)通过Metamask插件提供JSON RPC中的web3.personal.sign

服务器端调用对应的JSON RPC以从签名中检索帐户:web3.personal.ecrecover。在本教程中,我们将构建一个Asp.Net Core 2项目作为API层,并构建一个简单的HTML/javascript客户端作为DApp,以实际演示此身份验证过程。

  • 1.从DApp用户单击登录按钮。这需要Metamask提供的web3对象。
  • 2.Metamask要求用户通过JSON RPC的web3.personal.sign签署消息。
  • 3.签名将发送到API层,该层通过JSON RPC的web3.personal.ecrecover验证帐户。
  • 4.验证后,API层将发布JWT。

先决条件

  • 1.为Chrome或Firefox安装Metamask插件。这个附加组件“将以太坊带到你的浏览器上”。实际上,Metamask提供了一个web3对象,用于与你的DApp中的以太坊区块链进行交互,处理你的私钥并在浏览器中管理交易。
  • 2.可选的。运行Geth节点。我将向你展示两种从签名中恢复以太坊帐户的方法,其中一种方法需要你的API层针对Geth节点调用JSON RPC。注意:Infura现在还不行,因为它们不允许大多数web3.personal.*的JSON RPC接口。出于开发目的,运行Geth节点非常简单。在生产环境中,出于安全考虑,运行Geth节点并不是一项简单的任务。最好的方法是依靠AWS或Azure提供的区块链即服务堆栈(BaaS)。
  • 3.开发堆栈:Visual Studio 2017和节点包管理器(NPM)。
  • 4.以太坊/Asp.Net核心/前端开发的基础知识,JWT认证流程的基础知识。

开始

打开Visual Studio 2017,创建EthereumJwtSolution并添加两个Asp.Net Core 2 Web应用程序项目:EthereumJwtApiEthereumJwtClient。为两个项目选择空项目脚手架。

EthereumJwtClient只是一个HTML/Javascript客户端。我们将在Asp.Net Core上构建客户端应用程序,只是为了在IIS Express上轻松运行它。

我们需要准备EthereumJwtApi来创建和处理JWT token,以保护一些安全端点。任务很简单,因为Asp.Net Core 2有一个内置的JWT机制,可以插入我们的应用程序。 打开Startup.cs并修改ConfigureServices方法:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = true,ValidateAudience = true,ValidateLifetime = true,ValidateIssuerSigningKey = true,ValidIssuer = Configuration["Jwt:Issuer"],ValidAudience = Configuration["Jwt:Audience"],IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))};});services.AddCors(options =>{options.AddPolicy("CorsPolicy",builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials().Build());});services.AddMvc();

然后修改Configure方法:

if (env.IsDevelopment())
{app.UseDeveloperExceptionPage();
}app.UseCors("CorsPolicy");app.UseAuthentication();app.UseMvc();

我们告诉我们的API应用程序使用JWT身份验证服务。为了与我们的用户合作,我们还需要配置Cors策略。我们在appsetting.json中定义设置JWT配置:

"Jwt": {"Key": "averysecretpassphrase", // A random and secure passhphrase"Issuer": "http://localhost:49443/", // This API base URI"Audience": "http://localhost:51149/" // The client base URI},

为测试目的创建一个简单的可能安全端点:

[Route("api/[controller]")]
public class ValuesController : Controller
{// GET api/values[HttpGet, Authorize]public IEnumerable<string> Get(){return new string[] { "Secret 1", "Secret 2" };}
}

TokenController.cs将处理JWT请求和相关的token问题:

[Route("api/[controller]")]
public class TokenController : Controller
{private IConfiguration _config;public TokenController(IConfiguration config){_config = config;}[AllowAnonymous][HttpPost]public async Task<IActionResult> CreateToken([FromBody]LoginVM login){var user = await Authenticate(login);if (user != null){var tokenString = BuildToken(user);return Ok(new { token = tokenString });}return Unauthorized();}private string BuildToken(UserVM user){var claims = new[] {new Claim(JwtRegisteredClaimNames.Sub, user.Account),new Claim(JwtRegisteredClaimNames.GivenName, user.Name),new Claim(JwtRegisteredClaimNames.Email, user.Email),new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())};var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);var token = new JwtSecurityToken(_config["Jwt:Issuer"],_config["Jwt:Audience"],claims,expires: DateTime.Now.AddMinutes(30),signingCredentials: creds);return new JwtSecurityTokenHandler().WriteToken(token);}private async Task<UserVM> Authenticate(LoginVM login){// TODO: this method will authenticate the user recovering the Ethereum address from signature using the Geth RPC web3.personal.ecrecover APIUserVM user = user = new UserVM { Account = login.Account, Name = string.Empty, Email = string.Empty };return user;}private async Task<UserVM> Authenticate2(LoginVM login){// TODO: This method will authenticate the user recovering his Ethereum address through underlaying offline ecrecover method.UserVM user = user = new UserVM { Account = login.Account, Name = string.Empty, Email = string.Empty };return user;}

这是一个典型的JWT控制器,核心方法,AuthenticateAuthenticate2尚未实现。一旦实现,他们将完成相同的工作:从签名中恢复以太坊地址,并检查它是否等于客户端提供的以太坊地址。

LoginVM表示客户端提供的用户凭据,UserVM表示“服务器端”登录用户:

public class LoginVM
{public string Signer { get; set; } // Ethereum account that claim the signaturepublic string Signature { get; set; } // The signaturepublic string Message { get; set; } // The plain messagepublic string Hash { get; set; } // The prefixed and sha3 hashed message
}public class UserVM
{public string Account { get; set; } // Unique account name (the Ethereum account)public string Name { get; set; } // The user namepublic string Email { get; set; } // The user Email
}

Authenticate方法将SignatureMessage属性作为ecRecover函数的输入,Authenticate2方法将采用SignatureHash属性。我稍后会解释其中的差异。

======================================================================

分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。

原文在这里以太坊 区块链 Asp.Net Core API

用以太坊区块链保证Asp.Net Core的API安全(上)相关推荐

  1. ​六号美术馆 基于以太坊区块链上的区块链游戏

    六号美术馆 是一个在以太坊网络上运行的分布式应用程序,使用专门开发的智能合约,让玩家可以在六号美术馆中购买.拥有和传输大师级美术珍藏("珍藏.收藏或馆藏"),然后用户可以在网站上观 ...

  2. solidity payable_以太坊区块链搭建与使用(五)-智能合约Solidity

    一.智能合约Solidity开发工具 1.remix-ide http://remix.ethereum.org/ 在线版本,也可以去github下载安装到本地.开发.编译.发布.执行.测试 2.re ...

  3. EOS区块链和以太坊区块链那个更好?

    显然,你已经听说过两个最受欢迎的智能合约区块链,但想知道EOS与以太坊之中哪个更好?或许你想比较一下两种技术?好吧,你来对了地方,因为我要告诉你你需要知道的一切! 在这个EOS vs Ethereum ...

  4. 以太坊区块链快速入门

    一.基本概念 1.什么是以太坊? 以太坊是由社区驱动的技术,为加密货币以太币(ETH)和成千上万的去中心化应用程序提供动力. 属于所有人的银行服务 现实生活中不是每个人都能使用金融服务.但是只要您有网 ...

  5. 以太坊区块链实现去中心化购物功能

    在当今的中国,网上购物已经成为了我们不可或缺的一部分,通过电商网站查看商品,下单购物,支付,付款到支付宝,买家收货确认后,货款自动打入卖家的账户,这些购物的体验多数人每天都可能发生.大家都知道,淘宝的 ...

  6. 将 Magic 与以太坊区块链一起使用

    在构建 Web 应用程序时,身份验证可能是一个令人头疼的问题. 开发人员需要决定他们想要实现的安全模式,并以正确的方式进行. Magic ,前身为 Fortmatic ,以其快速.无缝.单向的 Web ...

  7. .NetCore使用以太坊区块链简介

    本文描述了在dotNet核心中使用像以太坊这样的区块链平台的过程.目标受众是其他想要从以太坊开始的dotNet开发者.需要了解区块链.在本文中,我们构建了一个完整的示例,允许你与自定义编写的智能合约进 ...

  8. 以太坊区块链同步_以太坊69:如何在10分钟内建立完全同步的区块链节点

    以太坊区块链同步 by Lukas Lukac 卢卡斯·卢卡奇(Lukas Lukac) Ethereu M 69:如何在10分钟内建立完全同步的区块链节点 (Ethereum 69: how to ...

  9. 以太坊区块链_以太坊区块链搭建与使用(一)-私有链

    步骤 一.下载go语言,并配置环境变量 //以太坊源代码依赖的编译与运行环境 二.通过git clone以太坊源码(go-ethereum),并编译 一.go安装 step1:下载 官方(一般打不开) ...

最新文章

  1. iOS 开发 需要的版本管理工具,UI图,bug管理工具等
  2. 无法监控端口_如何使用snmp监控linux服务器
  3. %@taglib prefix=c uri=http://java.sun.com/jsp/jst1/core%报错
  4. 为sharepoint 2013 增加切换账户登陆菜单
  5. 远程连接管理软件 v1.0
  6. python类的属性和对象属性_Python打印对象的全部属性
  7. 学Web前端开发需要哪些基础?零基础小白该怎么入行?
  8. python二维向量运算_python中二维数组的Elementwise与or或运算
  9. weex入门指南--华岭
  10. java报数报到3的人_Java-n个人报数
  11. 野火stm32资源下载(视频,手册等)
  12. 接入淘宝客+拼多多(多多客)+京东进行优惠券推广
  13. #STM32 LCD12864编程即原理介绍
  14. Redcarpet 出现 Invalid id given错误解决办法
  15. 华硕服务器 bios 内存 1333 显示 800,华硕服务器bios设置
  16. Midjourney|文心一格prompt教程[Text Prompt(下篇)]:游戏、实物、人物、风景、动漫、邮票、海报等生成,终极模板教学
  17. Ogre开发日记(一)
  18. 推荐三大文献检索下载网站,超级实用!重点是免费
  19. 2018纪中夏季信息学集训总结
  20. Linux操作系统应用

热门文章

  1. php 中抽象类的作用,解释PHP中的抽象类。
  2. 最小的linux内核代码,带你阅读linux内核源码:下载源码、编译内核并运行一个最小系统...
  3. 在python中、如果异常并未被处理或捕捉_Python异常处理总结
  4. lisp封装成vla函数_[良心教程]分享最新最实用的按键精灵封装函数
  5. python作品_专业解读 | 制作游戏、开发APP、 爬虫采集数据等背后,Python全栈专业背后还有更大的世界...
  6. Linux这么多命令怎么记住?
  7. node mysql商城开发_GitHub - Ssipon/nideshop: NideShop:基于Node.js+MySQL开发的开源免费商城(api服务器端)...
  8. 对应版本_NET Framework 和对应的 Windows 版本
  9. java添加关闭窗口事件_Java开发网 - 如何给JInternalFrame类的窗口添加关闭事件?...
  10. html5转换成mp4视频,HTML5的canvas动画转视频MP4