using CloudBuilder.Core.Application.Builders; using CloudBuilder.Core.Application.Options; using CloudBuilder.Core.Application.Packs; using CloudBuilder.Core.Authorization; using CloudBuilder.Core.Extensions; using CloudBuilder.Core.Policy; using CloudBuilder.Core.Service; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.IdentityModel.Tokens; using System.Text; /* 使用JWT: 1.认证(AddAuthentication) 1.1开启Bearer认证 1.2注册JwtBearer服务 3.开启中间件(app.UseAuthentication()) 4.实现IAuthenticationService接口认证服务 5.实现IAuthorizationPermissionService接口授权服务 2.授权(AddAuthorization) 2.1无状态授权[Authorize] 1.2有状态授权[Authorize["Permission"]] AddAuthorization注册自定义授权 */ namespace CloudBuilder.Core.DependencyInjection.Authorization { [PackLevel(45)] public class AuthorizationPack : CloudBuilderPack { /// /// 获取 模块级别 /// public override PackLevel Level => PackLevel.Framework; /// /// 获取 模块启动顺序,模块启动的顺序先按级别启动,级别内部再按此顺序启动 /// public override int Order => 2; /// /// 将服务添加到依赖注入服务容器中 /// /// 依赖注入服务容器 /// public override IServiceCollection AddServices(IServiceCollection services, CloudBuilderBuilder builder) { /*策略授权 1.导入 Microsoft.AspNetCore.Authorization Microsoft.AspNetCore.Authentication.JwtBearer 2.具体实现逻辑交由外部的PermissionServices:IAuthorizationPermissionService来处理 */ CloudBuilderOptions section = builder.CloudBuilderOptions; if (section.Jwt == null) return services; var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(section.Jwt.Secret)), SecurityAlgorithms.HmacSha256); // 角色与接口的权限要求参数 var permissionRequirement = new PermissionRequirement(); //初始化认证信息 services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; //Token Validation Parameters x.TokenValidationParameters = new TokenValidationParameters { ClockSkew= TimeSpan.Zero, //通常,验证库(至少是MS之一)可以补偿时钟偏斜。 ClockSkew的默认值为5分钟。 ValidateIssuerSigningKey = true, //获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。 IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(section.Jwt.Secret)), //获取或设置一个System.String,它表示将使用的有效发行者检查代币的发行者。 ValidIssuer = section.Jwt.Issuer, //获取或设置一个字符串,该字符串表示将用于检查的有效受众反对令牌的观众。 ValidAudience = section.Jwt.Audience, ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, NameClaimType = ClaimPolicy.CLAINM_USERID, RoleClaimType = ClaimPolicy.ROLE, }; }); //启用全局授权(所有的Controller就无需加入Authorize属性,如果加入就会重复执行授权) if (section.EnableGlobalAuthorize) { services.Configure(options => { options.Filters.Add(new AuthorizeFilter()); }); } //初始化授权信息(使用自定义复杂的授权) services.AddAuthorization(options => { options.AddPolicy(AuthorizePolicy.PERMISSION, policy => policy.Requirements.Add(permissionRequirement)); }); var baseType = typeof(IAuthorize); var allAssemblies = CloudBuilderBuilder.GetAssemblies(); var types = allAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(type => type != baseType && type.HasImplementedRawGeneric(baseType)) .Where(x => x.IsClass).ToList(); foreach (var implementType in types) { services.AddScoped(implementType.GetInterfaces().FirstOrDefault(), implementType); } services.AddSingleton(new JwtGenerate(section.Jwt)); return services; } } }