136 lines
5.4 KiB
C#
136 lines
5.4 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 获取 模块级别
|
||
/// </summary>
|
||
public override PackLevel Level => PackLevel.Framework;
|
||
|
||
/// <summary>
|
||
/// 获取 模块启动顺序,模块启动的顺序先按级别启动,级别内部再按此顺序启动
|
||
/// </summary>
|
||
public override int Order => 2;
|
||
|
||
/// <summary>
|
||
/// 将服务添加到依赖注入服务容器中
|
||
/// </summary>
|
||
/// <param name="services">依赖注入服务容器</param>
|
||
/// <returns></returns>
|
||
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<MvcOptions>(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;
|
||
}
|
||
|
||
}
|
||
} |