在ASP.NET Core中实现一个Token base的身份认证

以前在web端的身份认证都是基于Cookie | Session的身份认证, 在没有更多的终端出现之前,这样做也没有什么问题,
但在Web API时代,你所需要面对的就不止是浏览器了,还有各种客户端,这样就有了一个问题,这些客户端是不知道cookie是什么鬼的。 (cookie其实是浏览器搞出来的小猫腻,用来保持会话的,但HTTP本身是无状态的, 各种客户端能提供的无非也就是HTTP操作的API)

而基于Token的身份认证就是应对这种变化而生的,它更开放,安全性也更高。

基于Token的身份认证有很多种实现方式,但我们这里只使用微软提供的API。

接下来的例子将带领大家完成一个使用微软JwtSecurityTokenHandler完成一个基于beare token的身份认证。

注意:这种文章属于Step by step教程,跟着做才不至于看晕,下载完整代码分析代码结构才有意义。

前期准备

  • 推荐使用VS2015 Update3作为你的IDE,下载地址:www.visualstudio.com

  • 你需要安装.NET Core的运行环境以及开发工具,这里提供VS版:www.microsoft.com/net/core

创建项目

在VS中新建项目,项目类型选择ASP.NET Core Web Application(.NET Core), 输入项目名称为CSTokenBaseAuth

Coding

  • 创建一些辅助类

    在项目根目录下创建一个文件夹Auth,并添加RSAKeyHelper.cs以及TokenAuthOption.cs两个文件

    • 在RSAKeyHelper.cs中

    using System.Security.Cryptography;


    namespace CSTokenBaseAuth.Auth

    {

        public class RSAKeyHelper

        {

            public static RSAParameters GenerateKey()

            {

                using (var key = new RSACryptoServiceProvider(2048))

                {

                    return key.ExportParameters(true);

                }

            }

        }

    }

    • 在TokenAuthOption.cs中


  • using System;

  • using Microsoft.IdentityModel.Tokens;


  • namespace CSTokenBaseAuth.Auth

  • {

  •     public class TokenAuthOption

  •     {

  •         public static string Audience { get; } = "ExampleAudience";

  •         public static string Issuer { get; } = "ExampleIssuer";

  •         public static RsaSecurityKey Key { get; } = new RsaSecurityKey(RSAKeyHelper.GenerateKey());

  •         public static SigningCredentials SigningCredentials { get; } = new SigningCredentials(Key, SecurityAlgorithms.RsaSha256Signature);


  •         public static TimeSpan ExpiresSpan { get; } = TimeSpan.FromMinutes(20);

  •     }

  • }

  • Startup.cs

    在ConfigureServices中添加如下代码:

  • services.AddAuthorization(auth =>{auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder().AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌).RequireAuthenticatedUser().Build());
    });
  • 完整的代码应该是这样

  • public void ConfigureServices(IServiceCollection services)
    {    // Add framework services.    services.AddApplicationInsightsTelemetry(Configuration);    // Enable the use of an [Authorize("Bearer")] attribute on methods and classes to protect.services.AddAuthorization(auth =>{auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder().AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌).RequireAuthenticatedUser().Build());});services.AddMvc();
    }
  • 在Configure方法中添加如下代码


  • 这段代码主要是Handle Error用的,比如当身份认证失败的时候会抛出异常,而这里就是处理这个异常的。

    接下来在相同的方法中添加如下代码,


  • 应用JwtBearerAuthentication

  • app.UseJwtBearerAuthentication(new JwtBearerOptions {TokenValidationParameters = new TokenValidationParameters {IssuerSigningKey = TokenAuthOption.Key,ValidAudience = TokenAuthOption.Audience,ValidIssuer = TokenAuthOption.Issuer,ValidateIssuerSigningKey = true,ValidateLifetime = true,ClockSkew = TimeSpan.FromMinutes(0)}
    });


  • 完整的代码应该是这样




  • 在Controllers中新建一个Web API Controller Class,命名为TokenAuthController.cs。我们将在这里完成登录授权

    在同文件下添加两个类,分别用来模拟用户模型,以及用户存储,代码应该是这样

  • public class User
    {  
  •    public Guid ID { get; set; }  
  •   public string Username { get; set; }  
      public string Password { get; set; }
    }
    public static class UserStorage
    {  
  •   public static List<User> Users { get; set; } = new List<User> {        new User {ID=Guid.NewGuid(),Username="user1",Password = "user1psd" },        new User {ID=Guid.NewGuid(),Username="user2",Password = "user2psd" },        new User {ID=Guid.NewGuid(),Username="user3",Password = "user3psd" }};
    }
  • 接下来在TokenAuthController.cs中添加如下方法

  • private string GenerateToken(User user, DateTime expires)
    {   
  •     var handler = new JwtSecurityTokenHandler();ClaimsIdentity identity = new ClaimsIdentity(        new GenericIdentity(user.Username, "TokenAuth"),        new[] {            new Claim("ID", user.ID.ToString())});    var securityToken = handler.CreateToken(new SecurityTokenDescriptor{Issuer = TokenAuthOption.Issuer,Audience = TokenAuthOption.Audience,SigningCredentials = TokenAuthOption.SigningCredentials,Subject = identity,Expires = expires});    return handler.WriteToken(securityToken);
    }


  • 该方法仅仅只是生成一个Auth Token,接下来我们来添加另外一个方法来调用它

    在相同文件中添加如下代码

  • [HttpPost]
    public string GetAuthToken(User user)
    {    var existUser = UserStorage.Users.FirstOrDefault(u => u.Username == user.Username && u.Password == user.Password);    if (existUser != null){        var requestAt = DateTime.Now;      
  •   var expiresIn = requestAt + TokenAuthOption.ExpiresSpan;      
  •   var token = GenerateToken(existUser, expiresIn);        return JsonConvert.SerializeObject(new {stateCode = 1,requertAt = requestAt,expiresIn = TokenAuthOption.ExpiresSpan.TotalSeconds,accessToken = token});}    else{        return JsonConvert.SerializeObject(new { stateCode = -1, errors = "Username or password is invalid" });}
    }


  • 接下来我们来完成授权验证部分

    在Controllers中新建一个Web API Controller Class,命名为ValuesController.cs

    在其中添加如下代码

    public string Get()
    {   
  •  var claimsIdentity = User.Identity as ClaimsIdentity;  
  • var id = claimsIdentity.Claims.FirstOrDefault(c => c.Type == "ID").Value;    return $"Hello! {HttpContext.User.Identity.Name}, your ID is:{id}";
    }


  • 为方法添加装饰属性

    [HttpGet]
    [Authorize("Bearer")]

    完整的文件代码应该是这样

  • using System.Linq;  
    using Microsoft.AspNetCore.Mvc; 
    using Microsoft.AspNetCore.Authorization; 
  • using System.Security.Claims;
  • namespace CSTokenBaseAuth.Controllers
  • {[Route("api/[controller]")]  
  •   public class ValuesController : Controller{[HttpGet][Authorize("Bearer")]       
  •         public string Get(){        
  •        var claimsIdentity = User.Identity as ClaimsIdentity;   
  •    var id = claimsIdentity.Claims.FirstOrDefault(c => c.Type == "ID").Value;        
  •        return $"Hello! {HttpContext.User.Identity.Name}, your ID is:{id}";}}
    }
  • 最后让我们来添加视图

    在Controllers中新建一个Web Controller Class,命名为LoginController.cs

    其中的代码应该是这样

  • using Microsoft.AspNetCore.Mvc; 
    namespace CSTokenBaseAuth.Controllers
    {[Route("[controller]/[action]")]   
        public class LoginController : Controller{  
  •          public IActionResult Index()
  •         {            return View();}}
    }


  • 在项目Views目录下新建一个名为Login的目录,并在其中新建一个Index.cshtml文件。

    代码应该是这个样子

  • <html xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body><button id="getToken">getToken</button><button id="requestAPI">requestAPI</button><script src="https://code.jquery.com/jquery-3.1.1.min.js"></script><script>$(function () {            var accessToken = undefined;$("#getToken").click(function () {$.post(                    "/api/TokenAuth",{ Username: "user1", Password: "user1psd" },                    function (data) {console.log(data);                        if (data.stateCode == 1){accessToken = data.accessToken;$.ajaxSetup({headers: { "Authorization": "Bearer " + accessToken }});}},                    "json");})$("#requestAPI").click(function () {$.get("/api/Values", {}, function (data) {alert(data);}, "text");})})    </script></body></html>


最后:完整的代码Sample以及运行手册,请访问:How to achieve a bearer token authentication and authorization in ASP.NET Core

原文地址:http://www.cnblogs.com/onecodeonescript/p/6061714.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 运算器,运算器的功能是什么

运算器的功能是加、减、乘、除四则运算&#xff0c;与、或、非、异或等逻辑操作&#xff0c;以及移位、比较和传送等操作&#xff0c;运算器的处理对象是数据&#xff0c;所以数据长度和计算机数据表明方法&#xff0c;对运算器的性能影响极大。本文操作环境&#xff1a;Window…

.NET Standard 2.0:整齐划一的目标

在两个月前公布.NET Standard 2.0时&#xff0c;微软认为新版标准的目标在于为现有的三个主要.NET平台&#xff1a;.NET Framework、.NET Core&#xff0c;以及Xamarin提供一个坚实的底层基础&#xff0c;并为未来满足树莓派或IoT等全新类型设备需求可能需要创建的分支提供支持…

两年来的core折腾之路几点总结,附上nginx启用http2拿来即用的配置

为什么要迁移&#xff0c;江湖上传说windows server的稳定性不如某某某&#xff0c;这类议题与八卦新闻没两样&#xff0c;不谈&#xff0c;如果windows的价钱能够和linux相同或者差异不至于那么大&#xff0c;我才懒得换&#xff0c;因为穷&#xff0c;这才是重点。 涉及IO路径…

Vue(笔记)

所有东西必须都在标签里面进行定义&#xff0c;都在div中 报错后不断npm和cnpm Vue简介 Vue (读音/vju/, 类似于view)是一套用于构建用户界面的渐进式框架&#xff0c;发布于2014年2月。与其它大型框架不同的是&#xff0c;Vue被设计为可以自底向上逐层应用。Vue的核心库只关…

java通过poi读取excel中的日期类型数据或自定义类型日期

java通过poi读取excel中的日期类型数据或自定义类型日期 Java 读取Excel表格日期类型数据的时候&#xff0c;读出来的是这样的 12-十月-2019&#xff0c;而Excel中输入的是 2019/10/12 或 2019-10-12 poi处理excel时&#xff0c;当excel没有明确指明是哪个类型的数据时&…

微软的FreeBSD社区推广活动 北京站,你没看错!微软现在是一家名副其实的开源公司

自2012年开始&#xff0c;微软云计算与企业事业部和Citrix思杰&#xff0c;NetApp达成合作&#xff0c;共同开发出第一版针对Hyper-V虚拟设备驱动以及相关的用户态程序&#xff0c;并将此称之为集成服务 (Integration Service) 。微软也紧密地和FreeBSD社区合作&#xff0c;所有…

别羡慕别人的舒服,静下心来坚持奋斗!!!

通常给家里打电话的时候是晚上23点之后&#xff0c;因为家里也知道我这边忙&#xff0c;我也知道家里23点之前也在忙&#xff0c;所以选择在23点之后和家里联系联系&#xff0c;聊聊家常。自从到济南3年之久&#xff0c;即使在忙也每隔3-5天就给家里通一次电话&#xff0c;每次…

Linux ss命令 报错,ECS Linux中ss命令显示连接状态的使用说明

1. ss命令可用来获取socket统计信息&#xff0c;这个命令输出的结果类似于netstat输出的内容&#xff0c;但是它能够显示更多更详细的TCP连接状态的信息&#xff0c;且比netstat更快更高效。ss命令能够从内核空间直接得到信息&#xff0c;netstat命令读取各种/proc 文件收集信息…

Asp.Net Core 通过中间件防止图片盗链

一、原理 要实现防盗链&#xff0c;我们就必须先理解盗链的实现原理&#xff0c;提到防盗链的实现原理就不得不从HTTP协议说起&#xff0c;在HTTP协议中&#xff0c;有一个表头字段叫referer&#xff0c;采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说&#xff0c…

linux软件可以在所有发行版运行吗,Linux通用的跨发行版的3大软件包管理器

前言本文主要介绍Linux系统上通用的跨发行版的3大软件包管理器。Linux系统上的软件包管理可能非常令人困惑&#xff0c;尤其是对于新手&#xff0c;因为不同的Linux发行版使用不同的包管理系统。在大多数情况下&#xff0c;最令人困惑的部分是软件包依赖项的解析和管理。例如&a…

Java IO: 管道

转载自 Java IO: 管道 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力。所以管道也可以作为数据源以及目标媒介。 你不能利用管道与不同的JVM中的线程通信(不同的进程)。在概念上&#xf…

一款全新的基于IntelliJ和ReSharper的跨平台.NET IDE

JetBrains Rider在今年一月份露面&#xff0c;后来的大部分时间被用在了内部早期预览版上&#xff0c;还没有为公开发布做好准备。而现在&#xff0c;我们可以下载早期预览版&#xff0c;并感受在IntelliJ平台上开发.NET是一种什么体验。早期预览版还存在一些问题&#xff0c;不…

mysql自动插入的时间不对 差8小时

MySQL插入时间差八小时问题的解决方法 更新时间&#xff1a;2019年12月15日 10:19:12 转载 作者&#xff1a;lankeren 这篇文章主要给大家介绍了关于MySQL插入时间差八小时问题的解决方法&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家学习或者使用MySQL具…

windows为什么把linux打败了,快二十年了,人们为什么还是没有抛弃 Windows 转向 Linux?...

原标题&#xff1a;快二十年了&#xff0c;人们为什么还是没有抛弃 Windows 转向 Linux&#xff1f;自伟大的 Linux 操作系统诞生以来&#xff0c; 许多网友都试图列举出 Linux 可能是更好选择的具体原因 &#xff0c;其中包括&#xff1a;Linux 上的更新速度很快&#xff0c;“…

Java IO 概述

转载自 Java IO 概述 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) 校对&#xff1a;方腾飞 在这一小节&#xff0c;我会试着给出Java IO(java.io)包下所有类的概述。更具体地说&#xff0c;我会根据类的用途对类进行分组。这个分组将会使你在未来的工…

ASP.NET Core WebListener 服务器

WebListener是一个只能运行在Windows上的ASP.NET Core web服务器&#xff0c;基于Http.Sys内核模块驱动构建。在不借助IIS作为反向代理服务器的情况下&#xff0c;WebListener可以替代Kestrel用来与直接与互联网相连。实际上&#xff0c;WebListener不能和IIS或IIS Express一起…

git删除本地分支、删除远程分支 复制分支

git删除本地分支、删除远程分支 It_BeeCoder 2019-05-15 09:47:20 80268 收藏 15 展开 https://blog.csdn.net/lihua5419/article/details/81706905 1、查看所有分支 git branch -a 2、查看当前所在分支 git branch 3、删除本地的bug_xzx分支 git branch -d bug_xzx 4…

ASP.NET Core的Kestrel服务器

Kestrel是一个基于libuv的跨平台ASP.NET Core web服务器&#xff0c;libuv是一个跨平台的异步I/O库。ASP.NET Core模板项目使用Kestrel作为默认的web服务器。 Kestrel支持以下功能&#xff1a; HTTPS用于启用不透明升级的WebSockets位于Nginx之后的高性能Unix sockets Kestrel …