From 87dc5b1363339cfbc5e48df9b9a0353d374a8c9d Mon Sep 17 00:00:00 2001 From: "454313500@qq.com" <454313500@qq.com> Date: Sun, 18 Apr 2021 15:16:14 +0800 Subject: [PATCH] v1.2.0 --- CC.Yi.API/CC.Yi.API.csproj | 1 + CC.Yi.API/Controllers/StudentController.cs | 55 ++++++++++++++++ CC.Yi.API/Extension/SwaggerExtension.cs | 76 ++++++++++++++++++++++ CC.Yi.API/Startup.cs | 41 +++++++++--- CC.Yi.Common/Cache/RedisCache.cs | 2 + CC.Yi.Common/Jwt/JwtConst.cs | 12 ++++ 6 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 CC.Yi.API/Extension/SwaggerExtension.cs create mode 100644 CC.Yi.Common/Jwt/JwtConst.cs diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index d2836df9..6b3e84cf 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -7,6 +7,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index b3301a7e..ecbe8d2f 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,15 +1,21 @@ using CC.Yi.API.Filter; using CC.Yi.Common; using CC.Yi.Common.Cache; +using CC.Yi.Common.Jwt; using CC.Yi.IBLL; using CC.Yi.Model; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; 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; namespace CC.Yi.API.Controllers @@ -61,12 +67,58 @@ namespace CC.Yi.API.Controllers return Result.Success(data); } + #region + //下面,权限验证 + #endregion + + //发送令牌 + [HttpGet] + public Result Login(string role) + { + string userName = "admin"; + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , + new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"), + new Claim(ClaimTypes.Name, userName), + new Claim(ClaimTypes.Role,role) + + }; + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + + var token = new JwtSecurityToken( + issuer: JwtConst.Domain, + audience: JwtConst.Domain, + claims: claims, + expires: DateTime.Now.AddMinutes(30), + signingCredentials: creds); + + var tokenData= new JwtSecurityTokenHandler().WriteToken(token); + return Result.Success("欢迎你!管理员!").SetData(new { token= tokenData }); + } + + [HttpGet] + [Authorize(Policy = "myadmin")]//基于策略的验证 + public Result MyAdmin() + { + return Result.Success("欢迎你!管理员!"); + } + + [HttpGet] + [Authorize(Roles ="user")]//基于角色的验证 + public Result MyUser() + { + return Result.Success("欢迎你!游客!"); + } + #region //下面,经典的 增删改查 即为简易--Yi意框架 //注意:请确保你的数据库中存在合理的数据 #endregion [HttpGet] + [DbContextFilter] public async Task GetTest()//查 { _logger.LogInformation("调用查方法"); @@ -74,6 +126,7 @@ namespace CC.Yi.API.Controllers return Result.Success("查询成功").SetData(data); } [HttpGet] + [DbContextFilter] public Result AddTest()//增 { _logger.LogInformation("调用增方法"); @@ -90,6 +143,7 @@ namespace CC.Yi.API.Controllers } [HttpGet] + [DbContextFilter] public Result RemoveTest()//删 { _logger.LogInformation("调用删方法"); @@ -103,6 +157,7 @@ namespace CC.Yi.API.Controllers } } [HttpGet] + [DbContextFilter] public Result UpdateTest()//改 { _logger.LogInformation("调用改方法"); diff --git a/CC.Yi.API/Extension/SwaggerExtension.cs b/CC.Yi.API/Extension/SwaggerExtension.cs new file mode 100644 index 00000000..6db50f61 --- /dev/null +++ b/CC.Yi.API/Extension/SwaggerExtension.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using System; +using System.IO; + +namespace CC.Yi.API.Extension +{ + /// + /// Swagger文档扩展方法 + /// + public static class SwaggerExtension + { + public static IServiceCollection AddSwaggerService(this IServiceCollection services) + { + var apiInfo = new OpenApiInfo + { + Title = "Yi意框架-API接口", + Version = "v1", + Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://jiftcc.com") } + }; + #region 注册Swagger服务 + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", apiInfo); + + //添加注释服务 + //为 Swagger JSON and UI设置xml文档注释路径 + //获取应用程序所在目录(绝对路径,不受工作目录影响,建议采用此方法获取路径使用windwos&Linux) + var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); + var apiXmlPath = Path.Combine(basePath, @"ApiDoc.xml");//控制器层注释 + var entityXmlPath = Path.Combine(basePath, @"Model\ModelDoc.xml");//实体注释 + //c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释 + //c.IncludeXmlComments(entityXmlPath); + + //添加控制器注释 + //c.DocumentFilter(); + + //添加header验证信息 + //c.OperationFilter(); + //var security = new Dictionary> { { "Bearer", new string[] { } }, }; + + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() + { + Description = "文本框里输入从服务器获取的Token。格式为:Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\" + Name = "Authorization",////jwt默认的参数名称 + In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中) + Type = SecuritySchemeType.ApiKey, + }); + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { new OpenApiSecurityScheme + { + Reference = new OpenApiReference() + { + Id = "Bearer", + Type = ReferenceType.SecurityScheme + } + }, Array.Empty() } + }); + }); + #endregion + + return services; + } + + public static void UseSwaggerService(this IApplicationBuilder app) + { + //在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务: + // Enable middleware to serve generated Swagger as a JSON endpoint. + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JwtTest v1")); + } + + } +} diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index 1e429dd7..55003dc4 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -1,14 +1,17 @@ using Autofac; using Autofac.Extras.DynamicProxy; +using CC.Yi.API.Extension; using CC.Yi.API.Filter; using CC.Yi.BLL; using CC.Yi.Common.Cache; using CC.Yi.Common.Castle; +using CC.Yi.Common.Jwt; using CC.Yi.DAL; using CC.Yi.IBLL; using CC.Yi.IDAL; using CC.Yi.Model; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; @@ -19,10 +22,12 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace CC.Yi.API @@ -39,19 +44,40 @@ namespace CC.Yi.API public void ConfigureServices(IServiceCollection services) { + // Jwt + services.AddAuthorization(options => + { + //ûڲԵ֤ + options.AddPolicy("myadmin", policy => + policy.RequireRole("admin")); + }); + + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true,//Ƿ֤Issuer + ValidateAudience = true,//Ƿ֤Audience + ValidateLifetime = true,//Ƿ֤ʧЧʱ + ClockSkew = TimeSpan.FromSeconds(30), + ValidateIssuerSigningKey = true,//Ƿ֤SecurityKey + ValidAudience = JwtConst.Domain,//Audience + ValidIssuer = JwtConst.Domain,//Issuerǰǩjwtһ + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//õSecurityKey + }; + }); + services.AddControllers(); - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" }); - }); + services.AddSwaggerService(); services.AddSession(); //ù Action filters = new Action(r => { - r.Filters.Add(typeof(DbContextFilter)); + //r.Filters.Add(typeof(DbContextFilter)); }); services.AddMvc(filters); @@ -117,8 +143,7 @@ namespace CC.Yi.API if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1")); + app.UseSwaggerService(); } //app.UseAuthentication(); @@ -126,7 +151,7 @@ namespace CC.Yi.API app.UseHttpsRedirection(); app.UseSession(); app.UseRouting(); - + app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => diff --git a/CC.Yi.Common/Cache/RedisCache.cs b/CC.Yi.Common/Cache/RedisCache.cs index a1273002..3e695f02 100644 --- a/CC.Yi.Common/Cache/RedisCache.cs +++ b/CC.Yi.Common/Cache/RedisCache.cs @@ -8,6 +8,8 @@ namespace CC.Yi.Common.Cache public class RedisCache : ICacheWriter { private RedisClient client; + public string redisIp { get; set; } + public RedisCache() { client = new RedisClient("127.0.0.1", 6379, "52013142020."); diff --git a/CC.Yi.Common/Jwt/JwtConst.cs b/CC.Yi.Common/Jwt/JwtConst.cs new file mode 100644 index 00000000..1e7713ff --- /dev/null +++ b/CC.Yi.Common/Jwt/JwtConst.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Jwt +{ + public class JwtConst + { + public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"; + public const string Domain = "http://localhost:5000"; + } +}