(原)NET CORE3.1自定義JWT授權驗證

原文鏈接地址:https://www.cnblogs.com/ruyun/p/12134290.html

<p>登錄獲取JWT</p> <pre><code> [ApiController] public class LoginController : ControllerBase { private readonly IOptions&lt;JwtOption&gt; options;

    public LoginController(IOptions&lt;JwtOption&gt; options)
    {
        this.options = options;
    }

    [HttpGet("/login")]
    [AllowAnonymous]
    public IActionResult Login([FromQuery]string username)
    {
        string roleType = username == "admin" ? "Administrator" : "Other";

        var claims = new Claim[]
        {
            new Claim("Role",roleType),
        };
        var token = new JwtToken(options.Value).GenerateToken(claims);
        return Ok(token);
    }
}

</code></pre>

<p>在初始控制器WeatherForecastController中Get上添加[Authorize]<br> <img id="img1577958291700" src="https://img2018.cnblogs.com/other/464394/202001/464394-20200102174820606-910924805.png"></p> <p>自定義token的生成幫助類</p> <pre><code> public class JwtToken { private readonly byte[] secret; private readonly string audience; private readonly string issuer; private readonly int expiresMinute;

    public JwtToken(JwtOption options)
    {
        secret = Encoding.ASCII.GetBytes(options.Secret);
        audience = options.Audience;
        issuer = options.Issuer;
        expiresMinute = options.ExpirationMinutes;
    }
    ///生成JWT
    public JwtResult GenerateToken(Claim[] claims)
    {
        var authTime = DateTime.UtcNow;
        var expiresAt = authTime.AddMinutes(expiresMinute);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Audience = audience,
            Issuer = issuer,
            Subject = new ClaimsIdentity(claims),
            Expires = expiresAt,
            SigningCredentials = new SigningCredentials(
                new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature)
        };
        var tokenHandler = new JwtSecurityTokenHandler();
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);
        return new JwtResult
        {
            access_token = tokenString,
            token_type = "Bearer",
            auth_time = new DateTimeOffset(authTime).ToUnixTimeSeconds(),
            expires_at = new DateTimeOffset(expiresAt).ToUnixTimeSeconds()
        };
    }
}
public class JwtResult
{
    /// &lt;summary&gt;
    /// access token
    /// &lt;/summary&gt;
    public string access_token { get; set; }
    /// &lt;summary&gt;
    /// token type
    /// &lt;/summary&gt;
    public string token_type { get; set; }
    /// &lt;summary&gt;
    /// 授權時間
    /// &lt;/summary&gt;
    public long auth_time { get; set; }
    /// &lt;summary&gt;
    /// 過期時間
    /// &lt;/summary&gt;
    public long expires_at { get; set; }
}
    public class JwtOption
{
    public string Secret { get; set; }
    public string Issuer { get; set; }
    public string Audience { get; set; }
    public int ExpirationMinutes { get; set; }
}

</code></pre>

<p>在Appsettings中添加</p> <pre><code> "Authorization": { "Secret": "qtiOLpT7mJQx239e2kgMheAH7B9lGQJnoxYRCb7KX3x1ogDEd55I7dJ1ziYptiTF", "Issuer": "https://www.cnblogs.com/ruyun/", "Audience": "https://www.cnblogs.com/ruyun/", "ExpirationMinutes": "2000" } </code></pre> <p>自定義授權類</p> <pre><code> public class PermissionRequirement : IAuthorizationRequirement { public string PermissionName { get; }

    public PermissionRequirement(string PermissionName)
    {
        this.PermissionName = PermissionName;
    }
}
public class PermissionRequirementHandler : AuthorizationHandler&lt;PermissionRequirement&gt;
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public PermissionRequirementHandler(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        var result = await httpContextAccessor.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
        if (!result.Succeeded)
        {
            context.Fail();
            return;
        }
        httpContextAccessor.HttpContext.User = result.Principal;
        var role = httpContextAccessor.HttpContext.User.FindFirst(c =&gt; c.Type == "Role");

        if (role != null)
        {
            var roleValue = role.Value;
            var permissions = RolePermissionCache.GetPermissions(role.Value);
            if (permissions.Contains(requirement.PermissionName))
            {
                context.Succeed(requirement);
            }
        }
        return;
    }
}

//權限動態緩存類 臨時替代數據庫
public class RolePermissionCache
{
    //實際在數據庫獲取與配置
    public static List&lt;string&gt; GetPermissions(string role)
    {
        switch (role)
        {
            case "Administrator":
                return new List&lt;string&gt;() { "Index", "CustomPermission" };
            case "Custom":
                return new List&lt;string&gt;() { "Index" };
        }
        return new List&lt;string&gt;();
    }
}
internal class PermissionPolicyProvider : IAuthorizationPolicyProvider
{
    //這裏默認使用自定義的授權模式
    public Task&lt;AuthorizationPolicy&gt; GetDefaultPolicyAsync()
    {
        var policy = new AuthorizationPolicyBuilder();
        policy.AddRequirements(new PermissionRequirement("CustomPermission"));
        return Task.FromResult(policy.Build());
    }

    public Task&lt;AuthorizationPolicy&gt; GetFallbackPolicyAsync()
    {
        return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
    }

    public Task&lt;AuthorizationPolicy&gt; GetPolicyAsync(string policyName)
    {
        var policy = new AuthorizationPolicyBuilder();
        policy.AddRequirements(new PermissionRequirement(policyName));
        return Task.FromResult(policy.Build());
    }
}

</code></pre>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章