打开vs for mac,新建asp.net web api空项目
项目名称随便取,选择好存放位置,点创建
删除WeatherForecastController.cs以及WeatherForecast.cs
打开Properties/launchSettings.json,修改weatherforecast为/
打开Nuget包管理器,添加包 Microsoft.AspNetCore.Authentication.JwtBearer
打开appsettings.json,添加token验证相关配置
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", // 添加Authentication节点 "Authentication": { "Issure": "Bitbits.Inc", "Audience": "LolipopClient", "SecurityKey": "4C6A8A8B-1B9F-12E7-60C4-123BC0BB5D25" } }
打开Startup.cs,修改ConfigureServices方法,添加service配置
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // 添加下面配置信息 services.AddAuthentication(options => { // 设置默认使用jwt验证方式 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { IConfigurationSection confSection = Configuration.GetSection("Authentication"); options.TokenValidationParameters = new TokenValidationParameters() { // 验证接收者 ValidateAudience = true, // 验证发布者 ValidateIssuer = true, // 验证过期时间 ValidateLifetime = true, // 验证秘钥 ValidateIssuerSigningKey = true, // 读配置Issure ValidIssuer = confSection["Issure"], // 读配置Audience ValidAudience = confSection["Audience"], // 设置生成token的秘钥 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(confSection["SecurityKey"])) }; }); }
接下来修改Configure方法,添加Authorization、Authentication中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); // 注意,这里的Authentication必须在Authorization上面 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
完整的Startup.cs如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; namespace jwtTest { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAuthentication(options => { // 设置默认使用jwt验证方式 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { IConfigurationSection confSection = Configuration.GetSection("Authentication"); options.TokenValidationParameters = new TokenValidationParameters() { // 验证接收者 ValidateAudience = true, // 验证发布者 ValidateIssuer = true, // 验证过期时间 ValidateLifetime = true, // 验证秘钥 ValidateIssuerSigningKey = true, // 读配置Issure ValidIssuer = confSection["Issure"], // 读配置Audience ValidAudience = confSection["Audience"], // 设置生成token的秘钥 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(confSection["SecurityKey"])) }; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); // 注意,这里的Authentication必须在Authorization上面 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
右键Controllers文件夹,新建类
选择ASP.NET Core,Web API控制器类,修改控制器名称后点击新建
打开刚刚新建的控制器类,删除红框选中内容
引入Microsoft.AspNetCore.Authorization,顺便修改写路由模板(图中箭头所指)并在控制器类中标注如下属性
Ps:这里的Authorize属性跟AllowAnonymous属性可以标注在方法或者类上面
完整的ValuesController.cs代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; // 引入下面这个包 using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace jwtTest.Controllers { [Route("api/[controller]")] // ApiController属性:框架自动注入参数校验、model类型推断等功能 [ApiController] // Authorize属性:给控制器的所有动作加上权限验证,会跳过标注了AllowAnonymous的方法 [Authorize] public class ValuesController : Controller { [HttpGet("noauth")] // AllowAnonymous属性:标注了AllowAnonymous的方法不需要权限验证 [AllowAnonymous] public string Get() { return "这个方法不需要权限校验"; } [HttpGet("auth")] public string Get2() { return "这个方法需要权限校验"; } } }
新建AuthController
删除红框所示,并做上属性标注
添加AuthController构造函数跟IConfiguration依赖注入,代码如下:
添加Login方法,代码如下:
完整的AuthController.cs代码如下:
using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; namespace jwtTest.Controllers { [ApiController] [Route("api/[controller]")] public class AuthController : Controller { private IConfiguration _configuration { get; set; } // 控制器注入Configuration依赖,方便获取appsettinfs.json中的SecurityKey public AuthController(IConfiguration config) { _configuration = config; } [HttpGet("login")] public ActionResult Login(string username, string password) { if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) { // token中的claims用于储存自定义信息,如登录之后的用户id等 var claims = new[] { new Claim("userId", username) }; // 获取SecurityKey var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("Authentication")["SecurityKey"])); var token = new JwtSecurityToken( issuer: _configuration.GetSection("Authentication")["Issure"], // 发布者 audience: _configuration.GetSection("Authentication")["Audience"], // 接收者 notBefore: DateTime.Now, // token签发时间 expires: DateTime.Now.AddMinutes(30), // token过期时间 claims: claims, // 该token内存储的自定义字段信息 signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256) // 用于签发token的秘钥算法 ); // 返回成功信息,写出token return Ok(new { code = 200, message = "登录成功", data = new JwtSecurityTokenHandler().WriteToken(token) }); } // 返回错误请求信息 return BadRequest(new { code = 400, message = "登录失败,用户名或密码为空" }); } } }
打开Postman,创建一个新的页面
在地址栏跟下面的请求表单处添加好相关参数
点击蓝色的Send按钮,底下会显示返回值
绿色框中显示的就是我们需要的token
新建一个Postman测试页面,填写好参数
先测试不需要权限认证的请求,结果如下:
接下来测试需要权限认证的请求,先不添加认证header
发送之后,获取返回值
接下来添加认证header,并再次发送请求
请求成功,返回了对应的请求体
至此,已经成功添加jwt权限控制