目录
- 简介
- 基于.Net Core 验证方式
-
Jwt获取Token
- 引入三方包
- 生成Token
- UserInfo
- JwtConfig
-
WebApi测试(获取Token)
- Program.cs
- appsetting.json
- Controller
-
.Net Core 验证(webApi)
- Progarm
- Contorller
-
.Net Core 授权
- 简介
- Program.cs
-
JwtAuthorization.cs
- 注意
- Autofac 注册授权服务
-
Controller
- 注意
简介
- Jwt分为三段 通过远点分割
- header => 描述这个token加密方式
- PlayLoad => 有效载荷,用户信息+自定义Claims信息Verify
- Signature => 签名, (头部信息base64处理,有效载荷base64处理) + 密钥
- 示例 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJFeHRlbmRlZDEiOiLml6Dkv6Hmga8iLCJFeHRlbmRlZDIiOiIiLCJFeHRlbmRlZDMiOiIiLCJFeHRlbmRlZDQiOiIiLCJFeHRlbmRlZDUiOiIiLCIxIjoi57O757uf566h55CG5ZGYIiwiMiI6IueUqOaIt-euoeeQhuWRmCIsImV4cCI6MTY4ODkwMTA2NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDg4IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo1MDg4In0.7J1J7yWj4ELHJZIwLKnT4RgcMu3rGAX5ACBFfCS0LWM
基于.Net Core 验证方式
- 生成jwtToken
- 标记[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
- 验证 Issuer
- 验证 Audience
- 验证 SecurityKey
- 验证自定义验证
- 验证完成可以正常访问接口
验证的那几步顺序可以直接在自定义验证中验证
Jwt获取Token
引入三方包
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.31.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
</ItemGroup>
生成Token
using Microsoft.IdentityModel.Tokens;
using Programming.DotNetCore.Function.Entity.Jwt;
using Programming.DotNetCore.Function.Interface.PasswordService;
using Programming.DotNetCore.Function.Password.Entity;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Programming.DotNetCore.Function.Password
{
public class JwtServices : IPassWordService
{
public string GetToken(UserInfo user,JwtConfig jwtConfig)
{
List<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName ?? ""),
new Claim("Extended1", user.Extended1 ?? ""),
new Claim("Extended2", user.Extended2 ?? ""),
new Claim("Extended3", user.Extended3 ?? ""),
new Claim("Extended4", user.Extended4 ?? ""),
new Claim("Extended5", user.Extended5 ?? ""),
};
if (user.Role is not null)
{
foreach (var item in user.Role)
{
claims.Add(new Claim(item.Id.ToString(), item.Role));
}
}
if(jwtConfig.SecurityKey == null)
{
throw new Exception("JwtConfig.SecurityKey 不能为空");
}
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SecurityKey));
SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
JwtSecurityToken token = new JwtSecurityToken(
issuer:jwtConfig.Issuer,
audience:jwtConfig.Audience,
claims:claims,
expires: DateTime.UtcNow.AddMinutes(jwtConfig.ExpiresMinutes),
signingCredentials:creds
);
string resultToken = new JwtSecurityTokenHandler().WriteToken(token);
return resultToken;
}
}
}
UserInfo
namespace Programming.DotNetCore.Function.Password.Entity
{
public class UserInfo
{
public string? UserName { get; set; }
public List<RoleInfo>? Role { get; set; }
public string? Extended1 { get; set; }
public string? Extended2 { get; set; }
public string? Extended3 { get; set; }
public string? Extended4 { get; set; }
public string? Extended5 { get; set; }
}
}
JwtConfig
namespace Programming.DotNetCore.Function.Entity.Jwt
{
public class JwtConfig
{
public string? Audience { get; set; }
public string? Issuer { get; set; }
public string? SecurityKey { get; set; }
public int ExpiresMinutes { get; set; }
}
}
WebApi测试(获取Token)
Program.cs
//读取Jwt配置
builder.Services.Configure<JwtConfig>(builder.Configuration.GetSection("JwtTokenOptions"));
appsetting.json
{
"JwtTokenOptions": {
"Issuer": "http://localhost:5088",
"Audience": "http://localhost:5088",
"SecurityKey": "kq4DY5N1eFJhscOkI7Zp4Nd0WNy9d9AEsN6Yjgdv9OxLyol66tzGBKT_7vwolN7GZ8EDwqJBwccjDJfb81ws5s3sbbP5wUzQ3-PcTSsD-Rueiu2rsOUZwg_NR3RBCwmtouV-832YV2trCjNTawLB1z0LMukWGFNaAJVZ8WdQcrYn6a0ko5oVhZqaHBgsCLEGiqPtoFsiCcrJTz1IvXHk9_cDSr2hwEmSl18GlkOtgCHFH8aidYth3aQHRHuClTi6Y9mYRJtqqK-FNQYq4ZP23DSGZGFejJFTnM9YMpppuTMLklhSGySwX8rfjZ_0L5ac18nHaykTaiC2fvH00W42qQ"
}
}
Controller
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Programming.DotNetCore.Function.Entity.Jwt;
using Programming.DotNetCore.Function.Interface.PasswordService;
using Programming.DotNetCore.Function.Password.Entity;
namespace Cnpc.Com.Ioc.WebApp.Controllers
{
[Route("api/[controller]/[Action]")]
[ApiController]
public class TestJwtController : ControllerBase
{
IPassWordService _passWordService;
JwtConfig _jwtconfig;
public TestJwtController(IPassWordService passWordService,IOptions<JwtConfig> jwtconfig)
{
_passWordService = passWordService;
_jwtconfig = jwtconfig.Value;
}
[HttpGet]
public IActionResult Login(string userName,string passWord)
{
string token = _passWordService.GetToken(new()
{
UserName = userName,
Extended1 = "无信息",
Role = new List<RoleInfo>()
{
new RoleInfo() { Id = "1",Role="系统管理员"} ,
new RoleInfo() { Id = "2",Role="用户管理员"} ,
}
}, new()
{
Audience = _jwtconfig.Audience,
Issuer= _jwtconfig.Issuer,
SecurityKey= _jwtconfig.SecurityKey,
ExpiresMinutes = 5,
});
return new JsonResult(new { token = token });
}
}
}
.Net Core 验证(webApi)
Progarm
添加JWT验证
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = jwtConfig.Issuer, //发行人
ValidateAudience = true,
ValidAudience = jwtConfig.Audience,//订阅人
ValidateIssuerSigningKey = true,
//对称加密密钥
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SecurityKey!)),
ValidateLifetime = true, //验证失效时间
ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值
RequireExpirationTime = true,
AudienceValidator = (audiences, securityToken, validationParameters) =>
{
return true;
},
LifetimeValidator = (notBefore,expires, securityToken, validationParameters) =>
{
return true;
}
};
});
读取配置文件
JwtConfig jwtConfig = new JwtConfig();
builder.Configuration.Bind("JwtTokenOptions", jwtConfig);
添加Swagger支持,api右上角可以写Token
builder.Services.AddSwaggerGen(c =>
{
//添加Jwt验证设置,添加请求头信息
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
//放置接口Auth授权按钮
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "Value Bearer {token}",
Name = "Authorization",//jwt默认的参数名称
In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
Type = SecuritySchemeType.ApiKey
});
}); ;
Contorller
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Programming.DotNetCore.Function.Entity.Jwt;
using Programming.DotNetCore.Function.Interface.PasswordService;
using Programming.DotNetCore.Function.Password.Entity;
namespace Cnpc.Com.Ioc.WebApp.Controllers
{
[Route("api/[controller]/[Action]")]
[ApiController]
public class TestJwtController : ControllerBase
{
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult TestApi()
{
//获取用户Claim信息
var user = HttpContext.User.Claims.Select(it => new { it.Type,it.Value});
return new JsonResult(user);
}
}
}
.Net Core 授权
简介
可以在数据库中进一步验证访问接口的权限
Program.cs
//jwt 授权
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("JwtPolicy", policy =>
{
//jwt 授权
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
//这里为自定义授权指定一下类
.AddRequirements(new UserRoleRequirement(JwtBearerDefaults.AuthenticationScheme));
});
});
JwtAuthorization.cs
注意
验证中涉及到 IUserServices 和 JwtAuthorization, 需要在ioc容器中注册一下,我这里使用的是Autofac注册,如果使用系统自带的注册可以这么写:
- builder.Services.AddTransient<IUserServices, IUserServices>();
- builder.Services.AddTransient<IAuthorizationHandler, JwtAuthorization>();
Autofac 注册授权服务
using Autofac;
using Autofac.Extras.DynamicProxy;
using Castle.DynamicProxy;
using Cnpc.Com.Ioc.Bll;
using Cnpc.Com.Ioc.Dal;
using Cnpc.Com.Ioc.IBll;
using Cnpc.Com.Ioc.IDal;
using Cnpc.Com.Ioc.Tools;
using Cnpc.Com.Ioc.WebApp.Authorization;
using Cnpc.Com.Ioc.WebApp.Filter.ActionFilter;
using Microsoft.AspNetCore.Authorization;
using Programming.DotNetCore.Function.Interface.PasswordService;
using Programming.DotNetCore.Function.Password;
namespace WepApiTest.Autofac
{
public class AutofacConfig : Module
{
protected override void Load(ContainerBuilder builder)
{
//ioc
builder.RegisterType<JwtAuthorization>().As<IAuthorizationHandler>();
builder.RegisterType<UserServices>().As<IUserServices>();
}
}
}
using Cnpc.Com.Ioc.IBll;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
namespace Cnpc.Com.Ioc.WebApp.Authorization
{
public class UserRoleRequirement : IAuthorizationRequirement
{
public string AuthenticateScheme;
public UserRoleRequirement(string authenticateScheme)
{
AuthenticateScheme = authenticateScheme;
}
}
public class JwtAuthorization : AuthorizationHandler<UserRoleRequirement>
{
IUserServices userSercices;
public JwtAuthorization(IUserServices userSercices)
{
this.userSercices = userSercices;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserRoleRequirement requirement)
{
string? userName = context.User.FindFirst(it => it.Type == ClaimTypes.Name)?.Value;
if (userSercices.IsAdmin(userName!))
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return Task.CompletedTask;
}
}
}
Controller
注意
唯一需要修改的地方就是这里, 指定Policy 为 Program.cs 中设置授权方案名称
- [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme,Policy = "JwtPolicy")]
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Programming.DotNetCore.Function.Entity.Jwt;
using Programming.DotNetCore.Function.Interface.PasswordService;
using Programming.DotNetCore.Function.Password.Entity;
namespace Cnpc.Com.Ioc.WebApp.Controllers
{
[Route("api/[controller]/[Action]")]
[ApiController]
public class TestJwtController : ControllerBase
{
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme,Policy = "JwtPolicy")]
public IActionResult TestApi()
{
var user = HttpContext.User.Claims.Select(it => new { it.Type,it.Value});
return new JsonResult(user);
}
}
}
版权声明:除特别声明外,本站所有文章皆是本站原创,转载请以超链接形式注明出处!