授权与认证

使用JWT进行授权验证的步骤

服务注册与参数配置

新建一个.Net6类库,在类库下新建Helper文件夹,并创建Appsetting类,该类用于帮助读取Appsetting.json中的系统配置参数

通过Nuget安装Microsoft.Extensions.Configuration;Microsoft.Extensions.Caching.Abstractions;Microsoft.Extensions.Configuration.Json;Microsoft.Extensions.Configuration.Binder并完成Appsettings类

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class AppSettings
{
    static IConfiguration Configuration { get; set; }
    static string ContentPath { get; set; }
 
    public AppSettings()
    {
        string path = "appsettings.json";
        Configuration = new ConfigurationBuilder().SetBasePath(ContentPath).Add(new JsonConfigurationSource { Path = path, Optional = false, ReloadOnChange = true }).Build();
    }
    public AppSettings(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    public static string app(params string[] sections)
    {
        try
        {
            if (sections.Any())
            {
                return Configuration[string.Join(":", sections)];
            }
        }
        catch (Exception ex)
        {
 
        }
        return "";
    }
 
    public static List<T>app<T>(params string[] sections)
    {
        List<T> list=new List<T>();
        Configuration.Bind(string.Join(":", sections), list);
        return list;
    }
 
 
}

在Helper文件夹下继续新建JwtHelper类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class JWTHelper
{
    public static string IssueJwt(TokenModelJwt tokenModel)
    {
        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 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()}"),
            new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"),
            new Claim(ClaimTypes.Expiration,DateTime.Now.AddSeconds(1000).ToString()),
            new Claim(JwtRegisteredClaimNames.Iss,iss),
            new Claim(JwtRegisteredClaimNames.Aud,aud)
        };
        claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
        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();
        TokenModelJwt tokenModelJwt = new TokenModelJwt();
        if (!string.IsNullOrEmpty(jwtStr) && jwtHandler.CanReadToken(jwtStr))
        {
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            object role;
            jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
            tokenModelJwt = new TokenModelJwt
            {
                Uid = Convert.ToInt32(jwtToken.Id),
                Role = role == null ? "" : role.ToString()
            };
        }
        return tokenModelJwt;
    }
 
}

 设计登录接口 

1
2
3
4
5
6
7
8
9
10
11
12
13
    [ApiController]
    [Route("api/[controller]")]
    public class LoginController : Controller
    {
        [HttpGet]
        public async Task<object> GetJwtStr(string name, string pass)
        {
            TokenModelJwt tokenModelJwt = new TokenModelJwt { Uid = 1, Role = "Admin" };
            var jwtStr = JWTHelper.IssueJwt(tokenModelJwt);
            return Ok(new { success = true, token = jwtStr });
        }
    }
}

使用Swagger作为文档,已经实现了录入Token令牌的功能

在Nuget中搜索Swashbuckle.AspNetCore.Filters,在 ConfigureServices中的AddSwaggerGen服务中增加以下代码 

1
2
3
4
5
6
7
8
9
10
11
12
13
builder.Services.AddSwaggerGen(c =>
{
    c.OperationFilter<AddResponseHeadersFilter>();
    c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
    c.OperationFilter<SecurityRequirementsOperationFilter>();
    c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
        Description = "JWT授权",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey
    });
});

基于策略的授权机制

1
2
3
4
5
6
7
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
    option.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
    option.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
    option.AddPolicy("SystemAndAdmin", policy => policy.RequireRole("Admin").RequireRole("System"));
});

  

直接在API上设置该接口所对应的角色权限信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[ApiController]
 [Route("[controller]")]
 [Authorize(Policy = "Admin")]
 public class WeatherForecastController : ControllerBase
 {
     private static readonly string[] Summaries = new[]
     {"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"};
 
     private readonly ILogger<WeatherForecastController> _logger;
 
     public WeatherForecastController(ILogger<WeatherForecastController> logger)
     {
         _logger = logger;
     }
 
     [HttpGet(Name = "GetWeatherForecast")]
     public IEnumerable<WeatherForecast> Get()
     {
         return Enumerable.Range(1, 5).Select(index => new WeatherForecast
         {
             Date = DateTime.Now.AddDays(index),
             TemperatureC = Random.Shared.Next(-20, 55),
             Summary = Summaries[Random.Shared.Next(Summaries.Length)]
         })
         .ToArray();
     }
 }

配置认证服务

只需要在configureService中添加“统一认证”即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    var audienceConfig = builder.Configuration["Audience:Audience"];
    var symmetricKeyBase64 = builder.Configuration["Audience:Secret"];
    var iss = builder.Configuration["Audience:Issuer"];
    var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyBase64);
    var signingKey = new SymmetricSecurityKey(keyByteArray);
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,
        ValidateIssuer = true,
        ValidIssuer = iss,
        ValidateAudience = true,
        ValidAudience = audienceConfig,
        ValidateLifetime = true,
        ClockSkew = TimeSpan.Zero,
        RequireExpirationTime = true
    };
});

配置官方认证中间件

app.UseAuthentication()

posted on   血气方刚  阅读(73)  评论(0编辑  收藏  举报

(评论功能已被禁用)
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示