【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET Core 2.2 Web API 学习笔记概览

马肤

温馨提示:这篇文章已超过448天没有更新,请注意相关的内容是否还可用!

摘要:本学习笔记涵盖了ASP.NET Core 2.2 Web API的相关知识和实践。内容包括ASP.NET Core的基础概念、Web API的设计与开发、路由配置、数据模型定义、请求处理和数据返回等关键方面。通过学习和实践,读者能够掌握使用ASP.NET Core 2.2构建Web API的基本技能和最佳实践。

当年刚接触 ASP.NET Core 2.2 时,留下的学习笔记。现在把它挪到 CSDN,也是对过去学习 ASP.NET Core 痕迹进行记录。

VS 2019 + ASP.NET Core 2.2 + sqlSugarCore (ORM)

1. 仓储模式 + 服务 + 抽象接口

1.1 新建asp.net core 2.2 WebApi项目

nmmking.Core.Api

nmmking.Core.Common

nmmking.Core.IRepository

nmmking.Core.IServices

nmmking.Core.Model

nmmking.Core.Repository

nmmking.Core.Services

nmmking.Core.Test

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第1张

2.nmmking.Core.Model 使用 Sqlsuger Code first

2.1用 nuget 安装 sqlSugarCore ,新建 model 类

namespace nmmking.Core.Model.Models
{
    public class User
    {
        [SugarColumn(IsNullable =false,IsPrimaryKey =true,IsIdentity =true)]
        public int Id { get; set; }
        [SugarColumn(Length =50)]
        public string Name { get; set; }
        [SugarColumn(Length =50,IsNullable =true)]
        public string Password { get; set; }
    }
}

2.2 新建IDbContext接口

namespace nmmking.Core.Model
{
    public interface IDbContext
    {
        /// 
        /// 操作数据库对象
        /// 
        SqlSugarClient db { get; }
        /// 
        /// 创建数据表
        /// 
        /// 是否备份
        /// string类型映射的长度
        /// 要创建的数据表
        void CreateTable(bool Backup = false, int StringDefaultLength = 50, params Type[] types);
        /// 
        /// 创建表
        /// 
        /// 是否备份
        /// string类型映射的长度
        //public void CreateAllTable(bool Backup = false, int StringDefaultLength = 50);
    }
}

2.3 新建MyContext类

public class MyContext: IDbContext
    {
        public SqlSugarClient db
        {
            get
            {
                return new SqlSugarClient(new ConnectionConfig()
                {
                    ConnectionString = "server=.;database=nmmkingCoreDb;uid=sa;pwd=123456;",
                    DbType = DbType.SqlServer,//数据库类型
                    IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放
                    InitKeyType = InitKeyType.Attribute,//从实体特性中读取主键自增列信息
                });
            }
        }
        //public static SqlSugarClient GetInstance()
        //{
        //    db = new SqlSugarClient(new ConnectionConfig()
        //    {
        //        ConnectionString = "server=.;database=StudentDb;uid=sa;pwd=123456;",
        //        DbType = DbType.SqlServer,//设置数据库类型
        //        IsAutoCloseConnection = true,//自动释放数据库,如果存在事务,在事务结束之后释放。
        //        InitKeyType = InitKeyType.Attribute//从实体特性中读取主键自增列信息   
        //    });
        //    //db.Aop.OnLogExecuting = (sql, pars) =>
        //    //{
        //    //    Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject
        //    //        (pars.ToDictionary(it => it.ParameterName, it => it.Value)));
        //    //    Console.WriteLine();
        //    //};
        //    return db;
        //}
        public void CreateTable(bool Backup = false, int StringDefaultLength = 50, params Type[] types)
        {
            //设置varchar的默认长度
            db.CodeFirst.SetStringDefaultLength(StringDefaultLength);
            db.DbMaintenance.CreateDatabase();
            //创建表
            if (Backup)
            {
                db.CodeFirst.BackupTable().InitTables(types);
            }
            else
            {
                db.CodeFirst.InitTables(types);
            }
        }
        public SimpleClient userDb { get { return new SimpleClient(db); } }
        //public SqlSugarClient db => throw new NotImplementedException();
    }

2.4 使用

namespace nmmking.Core.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            MyContext context = new MyContext();
            context.CreateTable(false, 50, typeof(User));
            //AppDbContext context = new AppDbContext();
            //context.CreateTable(false, 50, typeof(Students), typeof(Schools));
            Console.WriteLine("Hello World!");
        }
    }
}

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第2张

3. 仓储层

3.1 IBaseRepository

namespace nmmking.Core.IRepository
{
    public interface IBaseRepository where T:class
    {
        Task QueryById(object id, bool IsUseCache = false); //根据id查询
        Task GetEntities(Expression whereLambda); //根据查询条件查询
        Task Add(T entity);
        Task DeleteById(object Id);
        Task Update(T entity);
    }
}

3.2 BaseRepository

namespace nmmking.Core.Repository
{
    public class BaseRepository : IBaseRepository where T : class, new()
    {
        private readonly IDbContext _dbContext;
        public BaseRepository(IDbContext dbContext)
        {
            this._dbContext = dbContext;
        }
        // 增加单条数据
        public async Task Add(T entity)
        {
            return await _dbContext.db.Insertable(entity).ExecuteCommandAsync() > 0;
        }
        // 根据id删除单条数据
        public async Task DeleteById(object id)
        {
            return await _dbContext.db.Deleteable(id).ExecuteCommandHasChangeAsync();
        }
        // 查询数据列表
        public async Task GetEntities(Expression whereExpression)
        {
            return await _dbContext.db.Queryable().WhereIF(whereExpression != null, whereExpression).ToListAsync();
        }
        // 根据Id查询一条数据
        public async Task QueryById(object id, bool IsUseCache =false)
        {
            return await _dbContext.db.Queryable().WithCacheIF(IsUseCache).In(id).SingleAsync();
        }
        // 更新实体数据
        public Task Update(T entity)
        {
            var i = await Task.Run(() => dbcontext.Updateable(model).ExecuteCommand());
            return i > 0;
        }
    }
}

4.读取 appsettings.json 文件

4.1 nuget 安装 Microsoft.Extensions.Configuration.Binder,Microsoft.Extensions.Configuration.Json。

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第3张

4.2 新建 Appsettings 类

namespace nmmking.Core.Common.Helper
{
    /// 
    /// appsettings.json操作类
    /// 
    public class Appsettings
    {
        static IConfiguration Configuration { get; set; }
        static string contentPath { get; set; }
        static Appsettings()
        {
            //如果你把配置文件 是 根据环境变量来分开了,可以这样写
            //Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";
            Configuration = new ConfigurationBuilder()
               .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })//请注意要把当前appsetting.json 文件->右键->属性->复制到输出目录->始终复制
               .Build();
        }
        /// 
        /// 封装要操作的字符
        /// 
        /// 节点配置
        /// 
        public static string app(params string[] sections)
        {
            try
            {
                if (sections.Any())
                {
                    return Configuration[string.Join(":", sections)];
                }
            }
            catch (Exception) { }
            return "";
        }
        /// 
        /// 递归获取配置信息数组
        /// 
        /// 
        /// 
        /// 
        public static List app(params string[] sections)
        {
            List list = new List();
            // 引用 Microsoft.Extensions.Configuration.Binder 包
            Configuration.Bind(string.Join(":", sections), list);
            return list;
        }
    }
}

4.3 使用

string iss = Appsettings.app(new string[] { "Audience", "Issuer" });
string aud = Appsettings.app(new string[] { "Audience", "Audience" }); 

5.使用Cors跨域

5.1 允许所有域名访问接口

在Startup.cs文件的ConfigureServices方法添加:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddCors(c => 
            {
                c.AddPolicy("LimitRequests", policy => 
                {
                    policy
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
            services.AddTransient(typeof(IBaseRepository), typeof(BaseRepository));
            services.AddTransient();
            services.AddTransient();
        }
在Startup.cs文件的 Configure 方法 添加:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseCors("LimitRequests");
        app.UseMvc();
}

运行:http://localhost:61576/api/values

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第4张

测试一下,打开百度地址:https://www.baidu.com/,按F12,在Console输入:

$.get("http://localhost:61576/api/values",function(data,status){
	console.log(data);
});

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第5张

5.2 限制域的访问

            services.AddCors(c => 
            {
                c.AddPolicy("LimitRequests", policy => 
                {
                    policy
                    //.AllowAnyOrigin()
                    .WithOrigins(new string[]{ "http://localhost:8881" })
                    //.WithOrigins(Appsettings.app(new string[] { "Startup", "Cors", "IPs" }).Split(','))
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors("LimitRequests");
            app.UseMvc();
        }

5.3 跨域访问

下载 nginx ,http://nginx.org/en/download.html,配置 nginx。

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第6张

新建 index.html




$(document).ready(function(){
	$.get("http://localhost:61576/api/values",function(data,status){
		alert(data);
		console.log(data);
	});
});



If you click on me, I will disappear.

出现跨域问题

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第7张

修改访问地址

            services.AddCors(c => 
            {
                c.AddPolicy("LimitRequests", policy => 
                {
                    policy
                    //.AllowAnyOrigin()
                    .WithOrigins(new string[]{ "http://localhost:8889" })
                    //.WithOrigins(Appsettings.app(new string[] { "Startup", "Cors", "IPs" }).Split(','))
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
刷新一下index.html,弹出界面,访问成功

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第8张

6.使用Log4Net日志处理

安装

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第9张

注册服务

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                 .UseStartup()
                    .ConfigureLogging((hostingContext, builder) =>
                    {
                        //过滤掉系统默认的一些日志
                        builder.AddFilter("System", LogLevel.Error);
                        builder.AddFilter("Microsoft", LogLevel.Error);
                        //builder.AddFilter();
                        //可配置文件
                        var path = Path.Combine(Directory.GetCurrentDirectory(),
                            "Log4net.config");
                        builder.AddLog4Net(path);
                    });

配置文件,下面文件配置了error和info两种级别的日志


	
	
	
	
		
		
		
		
		
		
		
		
		
		
		
			
		
		
			
			
		
	
	
	
	
		
		
		
		
		
		
		
		
		
		
		
		
			
		
		
			
			
		
	
	
	
		
		
		
		
		
		
		
	

使用

[Produces("application/json")]
    [Route("api/Values")]
    [AllowAnonymous]
    public class ValuesController : ControllerBase
    {
        private readonly IUserService _userService;
        private readonly ILogger _logger;
        public ValuesController(IUserService userService,ILogger logger)
        {
            this._userService = userService;
            this._logger = logger;
        }
        // GET api/values
        [HttpGet]
        public ActionResult Get()
        {
            _logger.LogError("this is an error");
            return new string[] { "value1", "value2" };
        }
}

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第10张

7.JWT基于策略的授权

安装 Microsoft.IdentityModel.Tokens 和 System.IdentityModel.Tokens.Jwt

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第11张

新建Jwt操作

 public class JwtHelper
    {
        /// 
        /// 颁发JWT字符串
        /// 
        /// 
        /// 
        public static string IssueJWT(TokenModelJWT tokenModel)
        {
            var dateTime = DateTime.UtcNow;
            string iss = Appsettings.app(new string[] { "Audience", "Issuer" });
            string aud = Appsettings.app(new string[] { "Audience", "Audience" });
            string secret = Appsettings.app(new string[] { "Audience", "Secret" });
            //var claims = new Claim[] //old
            var claims = new List
                {
                    //下边为Claim的默认配置
                new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                //这个就是过期时间,目前是过期100秒,可自定义,注意JWT有自己的缓冲过期时间
                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Iss,iss),
                new Claim(JwtRegisteredClaimNames.Aud,aud),
                //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
               };
            // 可以将一个用户的多个角色全部赋予;
            // 作者:DX 提供技术支持;
            claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
            //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwt = new JwtSecurityToken(
                issuer: iss,
                claims: claims,
                signingCredentials: creds);
            var jwtHandler = new JwtSecurityTokenHandler();
            var encodedJwt = jwtHandler.WriteToken(jwt);
            return encodedJwt;
        }
        /// 
        /// 解析
        /// 
        /// 
        /// 
        public static TokenModelJWT SerializeJWT(string jwtStr)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            object role = new object(); ;
            try
            {
                jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            var tm = new TokenModelJWT
            {
                Uid = Convert.ToInt32(jwtToken.Id),
                Role = role != null ? role.ToString() : "",
            };
            return tm;
        }
    }
    /// 
    /// 令牌
    /// 
    public class TokenModelJWT
    {
        /// 
        /// Id
        /// 
        public long Uid { get; set; }
        /// 
        /// 角色
        /// 
        public string Role { get; set; }
        /// 
        /// 职能
        /// 
        public string Work { get; set; }
    }

配置文件appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "Audience": {
    "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //至少要16位
    "Issuer": "nmmking.Core",
    "Audience": "yika"
  },
  "Startup": {
    "Cors": {
      "IPs": "http://127.0.0.1:2364,http://localhost:2364,http://localhost:8080,http://localhost:8021,http://localhost:1818"
    }
  },
    "AllowedHosts": "*"
  }
在Startup.cs文件注册和配置到管道

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第12张

            #region 基于策略的授权(简单版)
            // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。
            // 然后这么写 [Authorize(Policy = "Admin")]
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
                options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
                options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
            });
            #endregion
            #region 【认证】
            //读取配置文件
            var audienceConfig = Configuration.GetSection("Audience");
            var symmetricKeyAsBase64 = audienceConfig["Secret"];
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            //2.1【认证】
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
             .AddJwtBearer(o =>
             {
                 o.TokenValidationParameters = new TokenValidationParameters
                 {
                     ValidateIssuerSigningKey = true,
                     IssuerSigningKey = signingKey,
                     ValidateIssuer = true,
                     ValidIssuer = audienceConfig["Issuer"],//发行人
                     ValidateAudience = true,
                     ValidAudience = audienceConfig["Audience"],//订阅人
                     ValidateLifetime = true,
                     ClockSkew = TimeSpan.Zero,
                     RequireExpirationTime = true,
                 };
             });
            #endregion
app.UseAuthentication();

接口 GetJWTToken

    [Produces("application/json")]
    [Route("api/[controller]/[action]")]
    public class ValuesController : ControllerBase
    {
    }
  /// 
        /// 登录接口:随便输入字符,获取token,然后添加 Authoritarian
        /// 
        /// 
        /// 
        /// 
        [HttpGet]
        public async Task GetJWTToken(string name, string pass)
        {
            string jwtStr = string.Empty;
            bool suc = false;
            //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
            //这里直接写死了
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
            {
                return new JsonResult(new
                {
                    Status = false,
                    message = "用户名或密码不能为空"
                });
            }
            TokenModelJWT tokenModel = new TokenModelJWT();
            tokenModel.Uid = 1;
            tokenModel.Role = name;
            jwtStr = JwtHelper.IssueJWT(tokenModel);
            suc = true;
            return Ok(new
            {
                success = suc,
                token = jwtStr
            });
        }

测试1:测试 Get 

        /// 
        /// 这个也需要认证,只不过登录即可,不一定是Admin
        /// 
        /// 
        /// 
        [HttpGet]
        [Authorize]
        public ActionResult Get()
        {
            return "value";
        }
token 逾期,访问 Get 接口, 结果提示没有权限(未授权),如下图所示: 【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第13张

用户重新登录获取 token (这里没有指定的用户,只要登录就行),如下图所示:

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第14张

 ​​​​​​再次访问 Get 接口,访问成功如下图所示:【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第15张

接口2:

        /// 
        /// 这个需要认证,角色必须是Admin,其他的不需要
        /// 
        /// 
        [HttpGet]
        [Authorize(Policy = "SystemOrAdmin")]
        public ActionResult GetData()
        {
            _logger.LogError("this is an error");
            return new string[] { "value1", "value2" };
        }

随意的用户登录获取 token,如下所示

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第16张 登录的用户不是 Admin,结果是拒绝访问

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第17张

 如果是admin用户,请求参数和请求头如下:

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第18张

请求成功 

【笔记】ASP.NET Core 2.2 Web API —— 学习笔记,ASP.NET 学习笔记概览 第19张 

8.Swagger和JWT设置

nuget 安装 Microsoft.OpenApi ,Swashbuckle.AspNetCore,Swashbuckle.AspNetCore.Filters。

在Startup.cs设置:

private const string ApiName = "nmmking.Core.Api";
private readonly string version = "V1";
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors("LimitRequests");
            //注册异常处理中间件
            app.UseMiddleware();
            #region Swagger
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}");
                //c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("index.html");
                c.RoutePrefix = "";
            });
            #endregion
            // 开启权限
            app.UseAuthentication();
            app.UseMvc();
        }
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddCors(c => 
            {
                c.AddPolicy("LimitRequests", policy => 
                {
                    policy
                    //.AllowAnyOrigin()
                    .WithOrigins(new string[]{ "http://localhost:8881" })
                    //.WithOrigins(Appsettings.app(new string[] { "Startup", "Cors", "IPs" }).Split(','))
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });
            #region Swagger UI Service
            var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
            services.AddSwaggerGen(c =>
            {
                //遍历出全部的版本,做文档信息展示
                c.SwaggerDoc(version, new OpenApiInfo
                {
                    Version = version,
                    Title = $"{ApiName} 接口文档——{RuntimeInformation.FrameworkDescription}",
                    Description = $"{ApiName} HTTP API " + version,
                    Contact = new OpenApiContact { Name = ApiName, Email = "nmmking.Core@xxx.com", Url = new Uri("http地址") },
                    License = new OpenApiLicense { Name = ApiName + " 官方文档", Url = new Uri("http地址") }
                });
                c.OrderActionsBy(o => o.RelativePath);
                //就是这里
                var xmlPath = Path.Combine(basePath, "nmmking.Core.Api.xml");//这个就是刚刚配置的xml文件名
                c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改
                var xmlPath2 = Path.Combine(basePath, "nmmking.Core.Model.xml");
                c.IncludeXmlComments(xmlPath2, true);
                #region Token绑定到ConfigureServices
                // 开启加权小锁
                c.OperationFilter();
                c.OperationFilter();
                // 在header中添加token,传递到后台
                c.OperationFilter();
                // Jwt Bearer 认证,必须是 oauth2
                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
                    Name = "Authorization",//jwt默认的参数名称
                    In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                    Type = SecuritySchemeType.ApiKey
                });
                #endregion
            });
            #endregion
            #region 授权
            // 读取配置文件
            var audienceConfig = Configuration.GetSection("Audience");
            var symmetricKeyAsBase64 = audienceConfig["Secret"];
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); //签名
            // 角色与接口的权限要求参数
            var permissionRequirement = new PermissionRequirement(
                ClaimTypes.Role,//基于角色的授权
                audienceConfig["Issuer"],//发行人
                audienceConfig["Audience"],//听众
                signingCredentials,//签名凭据
                expiration: TimeSpan.FromSeconds(60 * 60)//接口的过期时间
                );
            // 授权
            services.AddAuthorization(options =>
            {
                // 权限变量配置
                options.AddPolicy("Permission",
                         policy => policy.Requirements.Add(permissionRequirement));
            });
            // 令牌验证参数
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidIssuer = audienceConfig["Issuer"],//发行人
                ValidateAudience = true,
                ValidAudience = audienceConfig["Audience"],//订阅人
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromSeconds(30),
                RequireExpirationTime = true,
            };
            services.AddAuthentication("Bearer")
             .AddJwtBearer(o =>
             {
                 o.TokenValidationParameters = tokenValidationParameters;
                 o.Events = new JwtBearerEvents
                 {
                     OnAuthenticationFailed = context =>
                     {
                         // 如果过期,则把添加到,返回头信息中
                         if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                         {
                             context.Response.Headers.Add("Token-Expired", "true");
                         }
                         return Task.CompletedTask;
                     }
                 };
             });
            services.AddSingleton(permissionRequirement);
            #endregion
            return services.BuildDynamicProxyProvider();
        }

 


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码