前言:
目前同学们对“net core doc”大体比较关切,兄弟们都需要分析一些“net core doc”的相关知识。那么小编也在网络上收集了一些关于“net core doc””的相关知识,希望姐妹们能喜欢,咱们一起来了解一下吧!JWT
JSON Web Token 经过数字签名后,无法伪造,一个能够在各方之间安全的传输JSON对象的开放标准(RFC 7519)
参考前文 [翻译]Introduction to JSON Web Tokens - 、天上月 - 博客园 (cnblogs.com)创建项目和解决方案
dotnet new webapi -n SampleApicd SampleApidotnet new sln -n SampleAppdotnet sln add .\SampleApi.csproj引用包
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
该包已经依赖Microsoft.IdentityModel.Tokens、System.IdentityModel.Tokens.Jwt,该包由Azure AD 团队提供,所以不在aspnetcore6 运行时中。
或直接修改jwtaspnetcore.csproj,引用包
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.1" />appsettings.json
"Authentication": { "JwtBearer": { "Issuer": ";, "Audience": "SampleApi", "SecurityKey": "SecurityKey23456" } }Issuer:令牌的颁发者。一般就写成域名,实际可任意Audience 颁发给谁。一般写成项目名,实际可任意SecurityKey:签名验证的KEY;至少 128bit ,即16个英文字符以上,实际可任意英文字符定义一个JwtSettings
public class JwtSettings{ public JwtSettings(byte[] key, string issuer, string audience) { Key = key; Issuer = issuer; Audience = audience; } /// <summary> ///令牌的颁发者 /// </summary> public string Issuer { get; } /// <summary> /// 颁发给谁 /// </summary> public string Audience { get; } public byte[] Key { get; } public TokenValidationParameters TokenValidationParameters => new TokenValidationParameters { //验证Issuer和Audience ValidateIssuer = true, ValidateAudience = true, ValidateIssuerSigningKey = true, //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, ValidIssuer = Issuer, ValidAudience = Audience, IssuerSigningKey = new SymmetricSecurityKey(Key) }; public static JwtSettings FromConfiguration(IConfiguration configuration) { var issuser = configuration["Authentication:JwtBearer:Issuer"] ?? "default_issuer"; var auidence = configuration["Authentication:JwtBearer:Audience"] ?? "default_auidence"; var securityKey = configuration["Authentication:JwtBearer:SecurityKey"] ?? "default_securitykey"; byte[] key = Encoding.ASCII.GetBytes(securityKey); return new JwtSettings(key, issuser, auidence); }}
中间件Middleware引用
app.UseAuthentication();//认证 app.UseAuthorization();//授权
定义JWT扩展方法服务注入
public static IServiceCollection AddJwt(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped<IStorageUserService, StorageUserService>(); var jwtSettings = JwtSettings.FromConfiguration(configuration); services.AddSingleton(jwtSettings); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => options.TokenValidationParameters = jwtSettings.TokenValidationParameters); return services; }引用服务
services.AddJwt(Configuration);
定义一个数据库的实体类,数据库访问 为模拟数据
public class SysUser{ public int Id { get; set; } public string UserName { get; set; }}
public interface IStorageUserService{ /// <summary> /// 根据登录验证用户 /// </summary> /// <param name="loginInfo"></param> /// <returns></returns> Task<SysUser> CheckPasswordAsync(LoginInfo loginInfo);}public class StorageUserService : IStorageUserService{ public async Task<SysUser> CheckPasswordAsync(LoginInfo loginInfo) { return await Task.FromResult( new SysUser { Id = new Random().Next(10000), UserName = loginInfo.UserName } ); }}AuthController登录GenerateToken
using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;using Microsoft.IdentityModel.Tokens;using SampleApi.Models;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;namespace SampleApi.Auth;/// <summary>/// 登录认证个人信息/// </summary>[ApiController][Route("/api/[controller]/[action]")][AllowAnonymous]public class AuthController : ControllerBase{ private readonly IStorageUserService _userService; private readonly JwtSettings _jwtSettings; public AuthController(JwtSettings jwtSettings, IStorageUserService userService) { _jwtSettings = jwtSettings; _userService = userService; } /// <summary> /// 登录,生成访问Toekn /// </summary> /// <param name="loginInfo"></param> /// <returns></returns> [HttpPost] public async Task<IActionResult> GenerateToken(LoginInfo loginInfo) { SysUser user = await _userService.CheckPasswordAsync(loginInfo); if (user == null) { return Ok(new { Status = false, Message = "账号或密码错误" }); } var claims = new List<Claim>(); claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); claims.Add(new Claim(ClaimTypes.Name, user.UserName)); var key = new SymmetricSecurityKey(_jwtSettings.Key); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: _jwtSettings.Issuer, audience: _jwtSettings.Audience, claims: claims, expires: DateTime.Now.AddMinutes(120), signingCredentials: creds ); return Ok(new { Status = true, Token = new JwtSecurityTokenHandler().WriteToken(token) }); }}
aspnetcore6默认集成了swagger,直接运行项目,实际上为模拟数据库请求,所以点击登录接口即可。
{ "status": true,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6Ijc4NjciLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoic3RyaW5nIiwiZXhwIjoxNjQzMDMyNzA1LCJpc3MiOiJodHRwOi8vYXBpLnNhbXBsZWFwaS5jb20iLCJhdWQiOiJTYW1wbGVBcGkifQ.Rl8XAt2u0aZRxEJw2mVUnV6S9WzQ65qUYjqXDTneCxE"}
当使用Swagger测试时,增加,可配置全局请求头。增加一个扩展方法。
services.AddSwagger(Configuration);
public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration) { services.AddSwaggerGen(options => { try { options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml"), true); } catch (Exception ex) { Log.Warning(ex.Message); } options.SwaggerDoc("v1", new OpenApiInfo { Title = "SampleApp - HTTP API", Version = "v1", Description = "The SampleApp Microservice HTTP API. This is a Data-Driven/CRUD microservice sample" }); options.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference() { Id = "Bearer", Type = ReferenceType.SecurityScheme } }, Array.Empty<string>() } }); options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme { Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", Name = "Authorization", //jwt默认的参数名称 In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中) Type = SecuritySchemeType.ApiKey }); }); services.AddEndpointsApiExplorer(); return services; }获取当前用户信息
/// <summary> /// 编码Token /// </summary> /// <param name="token"></param> /// <returns></returns> [HttpGet] [AllowAnonymous] public CurrentUser DecodeToken(string token) { var jwtTokenHandler = new JwtSecurityTokenHandler(); if (jwtTokenHandler.CanReadToken(token)) { JwtPayload jwtPayload = new JwtSecurityTokenHandler().ReadJwtToken(token).Payload; string? userIdOrNull = jwtPayload.Claims.FirstOrDefault(r => r.Type == ClaimTypes.NameIdentifier)?.Value; string? UserName = jwtPayload.Claims.FirstOrDefault(r => r.Type == ClaimTypes.Name)?.Value; CurrentUser currentUser = new CurrentUser { UserId = userIdOrNull == null ? null : Convert.ToInt32(userIdOrNull), UserName = UserName }; return currentUser; } return null; }根据请求头获取用户信息
IStorageUserService增加接口,StorageUserService的实现,创建一个CurrentUser类
public class StorageUserService : IStorageUserService{ private readonly IHttpContextAccessor _contextAccessor; public StorageUserService(IHttpContextAccessor contextAccessor) { _contextAccessor = contextAccessor; } public async Task<CurrentUser> GetUserByRequestContext() { var user = _contextAccessor.HttpContext.User; string? userIdOrNull = user.Claims?.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; string? UserName = user.Claims?.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value; CurrentUser currentUser = new CurrentUser { IsAuthenticated = user.Identity.IsAuthenticated, UserId = userIdOrNull == null ? null : Convert.ToInt32(userIdOrNull), UserName = UserName }; return await Task.FromResult(currentUser); }}public class CurrentUser{ /// <summary> /// 是否登录 /// </summary> public bool IsAuthenticated { get; set; } /// <summary> /// 用户Id /// </summary> public int? UserId { get; set; } /// <summary> /// 用户名 /// </summary> public string? UserName { get; set; }}public interface IStorageUserService{ /// <summary> /// 根据Request Header携带Authorization:Bearer+空格+AccessToken获取当前登录人信息 /// </summary> /// <returns></returns> Task<CurrentUser> GetUserByRequestContext();}AuthController调用服务
/// <summary> /// 根据Request Header携带Authorization:Bearer+空格+AccessToken获取当前登录人信息 /// </summary> /// <returns></returns> [HttpGet] [Authorize] public async Task<CurrentUser> GetUserByRequestContext() { return await _userService.GetUserByRequestContext(); }
在swagger右上角,点击Authorize,header的参数结构: "Authorization: Bearer+空格+ {token}"
原文连接:
欢迎点赞+转发+关注!大家的支持是我分享最大的动力!!!
标签: #net core doc