千家信息网

如何获取ASP.NETCoreToken的认证

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,如何获取ASP.NETCoreToken的认证,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。令牌认证(Token Aut
千家信息网最后更新 2026年11月02日如何获取ASP.NETCoreToken的认证

如何获取ASP.NETCoreToken的认证,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

令牌认证(Token Authentication)已经成为单页应用(SPA)和移动应用事实上的标准。即使是传统的B/S应用也能利用其优点。优点很明白:极少的服务端数据管理、可扩展性、可以使用单独的认证服务器和应用服务器分离。

如果你对令牌(token)不是太了解,可以看这篇文章( overview of token authentication and JWTs)

令牌认证在asp.net core中集成。其中包括保护Bearer Jwt的路由功能,但是移除了生成token和验证token的部分,这些可以自定义或者使用第三方库来实现,得益于此,MVC和Web api项目可以使用令牌认证,而且很简单。下面将一步一步实现,代码可以在( 源码)下载。

ASP.NET Core令牌验证

首先,背景知识:认证令牌,例如JWTs,是通过http 认证头传递的,例如:

GET /fooAuthorization: Bearer [token]

令牌可以通过浏览器cookies。传递方式是header或者cookies取决于应用和实际情况,对于移动app,使用headers,对于web,推荐在html5 storage中使用cookies,来防止xss攻击。

asp.net core对jwts令牌的验证很简单,特别是你通过header传递。

1、生成 SecurityKey,这个例子,我生成对称密钥验证jwts通过HMAC-SHA256加密方式,在startup.cs中:

// secretKey contains a secret passphrase only your server knowsvar secretKey = "mysupersecret_secretkey!123";var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

验证 header中传递的JWTs

在 Startup.cs中,使用Microsoft.AspNetCore.Authentication.JwtBearer中的UseJwtBearerAuthentication 方法获取受保护的api或者mvc路由有效的jwt。

var tokenValidationParameters = new TokenValidationParameters{  // The signing key must match!  ValidateIssuerSigningKey = true,  IssuerSigningKey = signingKey,  // Validate the JWT Issuer (iss) claim  ValidateIssuer = true,  ValidIssuer = "ExampleIssuer",  // Validate the JWT Audience (aud) claim  ValidateAudience = true,  ValidAudience = "ExampleAudience",  // Validate the token expiry  ValidateLifetime = true,  // If you want to allow a certain amount of clock drift, set that here:  ClockSkew = TimeSpan.Zero};app.UseJwtBearerAuthentication(new JwtBearerOptions{  AutomaticAuthenticate = true,  AutomaticChallenge = true,  TokenValidationParameters = tokenValidationParameters});

通过这个中间件,任何[Authorize]的请求都需要有效的jwt:

签名有效;

过期时间;

有效时间;

Issuer 声明等于"ExampleIssuer"

订阅者声明等于 "ExampleAudience"

如果不是合法的JWT,请求终止,issuer声明和订阅者声明不是必须的,它们用来标识应用和客户端。

在cookies中验证JWTs

ASP.NET Core中的cookies 认证不支持传递jwt。需要自定义实现 ISecureDataFormat接口的类。现在,你只是验证token,不是生成它们,只需要实现Unprotect方法,其他的交给System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler这个类处理。

using System;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Http.Authentication;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider{  public class CustomJwtDataFormat : ISecureDataFormat  {    private readonly string algorithm;    private readonly TokenValidationParameters validationParameters;     public CustomJwtDataFormat(string algorithm, TokenValidationParameters validationParameters)    {      this.algorithm = algorithm;      this.validationParameters = validationParameters;    }     public AuthenticationTicket Unprotect(string protectedText)      => Unprotect(protectedText, null);     public AuthenticationTicket Unprotect(string protectedText, string purpose)    {      var handler = new JwtSecurityTokenHandler();      ClaimsPrincipal principal = null;      SecurityToken validToken = null;       try      {        principal = handler.ValidateToken(protectedText, this.validationParameters, out validToken);         var validJwt = validToken as JwtSecurityToken;         if (validJwt == null)        {          throw new ArgumentException("Invalid JWT");        }         if (!validJwt.Header.Alg.Equals(algorithm, StringComparison.Ordinal))        {          throw new ArgumentException($"Algorithm must be '{algorithm}'");        }         // Additional custom validation of JWT claims here (if any)      }      catch (SecurityTokenValidationException)      {        return null;      }      catch (ArgumentException)      {        return null;      }       // Validation passed. Return a valid AuthenticationTicket:      return new AuthenticationTicket(principal, new AuthenticationProperties(), "Cookie");    }     // This ISecureDataFormat implementation is decode-only    public string Protect(AuthenticationTicket data)    {      throw new NotImplementedException();    }     public string Protect(AuthenticationTicket data, string purpose)    {      throw new NotImplementedException();    }  }}

在startup.cs中调用

var tokenValidationParameters = new TokenValidationParameters{  // The signing key must match!  ValidateIssuerSigningKey = true,  IssuerSigningKey = signingKey,   // Validate the JWT Issuer (iss) claim  ValidateIssuer = true,  ValidIssuer = "ExampleIssuer",   // Validate the JWT Audience (aud) claim  ValidateAudience = true,  ValidAudience = "ExampleAudience",   // Validate the token expiry  ValidateLifetime = true,   // If you want to allow a certain amount of clock drift, set that here:  ClockSkew = TimeSpan.Zero}; app.UseCookieAuthentication(new CookieAuthenticationOptions{  AutomaticAuthenticate = true,  AutomaticChallenge = true,  AuthenticationScheme = "Cookie",  CookieName = "access_token",  TicketDataFormat = new CustomJwtDataFormat(    SecurityAlgorithms.HmacSha256,    tokenValidationParameters)});

如果请求中包含名为access_token的cookie验证为合法的JWT,这个请求就能返回正确的结果,如果需要,你可以加上额外的jwt chaims,或者复制jwt chaims到ClaimsPrincipal在CustomJwtDataFormat.Unprotect方法中,上面是验证token,下面将在asp.net core中生成token。

ASP.NET Core生成Tokens

在asp.net 4.5中,这个UseOAuthAuthorizationServer中间件可以轻松的生成tokens,但是在asp.net core取消了,下面写一个简单的token生成中间件,最后,有几个现成解决方案的链接,供你选择。

简单的token生成节点

首先,生成 POCO保存中间件的选项. 生成类:TokenProviderOptions.cs

using System;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider{  public class TokenProviderOptions  {    public string Path { get; set; } = "/token";     public string Issuer { get; set; }     public string Audience { get; set; }     public TimeSpan Expiration { get; set; } = TimeSpan.FromMinutes(5);     public SigningCredentials SigningCredentials { get; set; }  }}

现在自己添加一个中间件,asp.net core 的中间件类一般是这样的:

using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Threading.Tasks;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Options;using Newtonsoft.Json;namespace SimpleTokenProvider{  public class TokenProviderMiddleware  {    private readonly RequestDelegate _next;    private readonly TokenProviderOptions _options;    public TokenProviderMiddleware(      RequestDelegate next,      IOptions options)    {      _next = next;      _options = options.Value;    }    public Task Invoke(HttpContext context)    {      // If the request path doesn't match, skip      if (!context.Request.Path.Equals(_options.Path, StringComparison.Ordinal))      {        return _next(context);      }      // Request must be POST with Content-Type: application/x-www-form-urlencoded      if (!context.Request.Method.Equals("POST")        || !context.Request.HasFormContentType)      {        context.Response.StatusCode = 400;        return context.Response.WriteAsync("Bad request.");      }      return GenerateToken(context);    }  }}

这个中间件类接受TokenProviderOptions作为参数,当有请求且请求路径是设置的路径(token或者api/token),Invoke方法执行,token节点只对 POST请求而且包括form-urlencoded内容类型(Content-Type: application/x-www-form-urlencoded),因此调用之前需要检查下内容类型。

最重要的是GenerateToken,这个方法需要验证用户的身份,生成jwt,传回jwt:

private async Task GenerateToken(HttpContext context){  var username = context.Request.Form["username"];  var password = context.Request.Form["password"];   var identity = await GetIdentity(username, password);  if (identity == null)  {    context.Response.StatusCode = 400;    await context.Response.WriteAsync("Invalid username or password.");    return;  }   var now = DateTime.UtcNow;   // Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.  // You can add other claims here, if you want:  var claims = new Claim[]  {    new Claim(JwtRegisteredClaimNames.Sub, username),    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),    new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64)  };   // Create the JWT and write it to a string  var jwt = new JwtSecurityToken(    issuer: _options.Issuer,    audience: _options.Audience,    claims: claims,    notBefore: now,    expires: now.Add(_options.Expiration),    signingCredentials: _options.SigningCredentials);  var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);   var response = new  {    access_token = encodedJwt,    expires_in = (int)_options.Expiration.TotalSeconds  };   // Serialize and return the response  context.Response.ContentType = "application/json";  await context.Response.WriteAsync(JsonConvert.SerializeObject(response, new JsonSerializerSettings { Formatting = Formatting.Indented }));}

大部分代码都很官方,JwtSecurityToken 类生成jwt,JwtSecurityTokenHandler将jwt编码,你可以在claims中添加任何chaims。验证用户身份只是简单的验证,实际情况肯定不是这样的,你可以集成 identity framework或者其他的,对于这个实例只是简单的硬编码:

private Task GetIdentity(string username, string password){  // DON'T do this in production, obviously!  if (username == "TEST" && password == "TEST123")  {    return Task.FromResult(new ClaimsIdentity(new System.Security.Principal.GenericIdentity(username, "Token"), new Claim[] { }));  }   // Credentials are invalid, or account doesn't exist  return Task.FromResult(null);}

添加一个将DateTime生成timestamp的方法:

public static long ToUnixEpochDate(DateTime date)  => (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);

现在,你可以将这个中间件添加到startup.cs中了:

using System.Text;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Microsoft.Extensions.Options;using Microsoft.IdentityModel.Tokens; namespace SimpleTokenProvider{  public partial class Startup  {    public Startup(IHostingEnvironment env)    {      var builder = new ConfigurationBuilder()        .AddJsonFile("appsettings.json", optional: true);      Configuration = builder.Build();    }     public IConfigurationRoot Configuration { get; set; }     public void ConfigureServices(IServiceCollection services)    {      services.AddMvc();    }     // The secret key every token will be signed with.    // In production, you should store this securely in environment variables    // or a key management tool. Don't hardcode this into your application!    private static readonly string secretKey = "mysupersecret_secretkey!123";     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)    {      loggerFactory.AddConsole(LogLevel.Debug);      loggerFactory.AddDebug();       app.UseStaticFiles();       // Add JWT generation endpoint:      var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));      var options = new TokenProviderOptions      {        Audience = "ExampleAudience",        Issuer = "ExampleIssuer",        SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),      };       app.UseMiddleware(Options.Create(options));       app.UseMvc();    }  }}

测试一下,推荐使用chrome 的postman:

POST /tokenContent-Type: application/x-www-form-urlencodedusername=TEST&password=TEST123

结果:
OK

Content-Type: application/json

{
"access_token": "eyJhb...",
"expires_in": 300
}

你可以使用jwt工具查看生成的jwt内容。如果开发的是移动应用或者单页应用,你可以在后续请求的header中存储jwt,如果你需要在cookies中存储的话,你需要对代码修改一下,需要将返回的jwt字符串添加到cookie中。
测试下:


看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

生成 验证 认证 中间件 令牌 应用 方法 有效 内容 代码 只是 服务 移动 合法 优点 实际 情况 方式 时间 服务器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网扶贫科技 没上市的科技互联网公司 互联网未来科技 华中科技大学互联网 有木互联网科技 伴你行互联网科技有限公司 狮子座互联网科技培训 四个字互联网科技公司取名 恒银科技与互联网金融 互联网对科技的发展 上海宁丞科技互联网 南通创西澳互联网科技有限公司 小米互联网科技园入驻 四川互联网展示科技馆设计 科技互联网行业投资研究 科技信息时代互联网发展 第三届互联网大会安防黑科技 数字科技和互联网金融哪个好 互联网科技创新方面的资料 互联网科技快速发展优美句子 互联网扶贫科技 九亚互联网科技 深圳卡尔迅互联网科技有限公司怎么样 深圳互联网科技怎么样 哈尔滨屹滨互联网科技有限公司 允成互联网科技有限公司融资 互联网科技实习生岗位 产业互联网科技服务公司 广西科技产业互联网是什么 青岛易易互联网科技
0