.net core 3.1 Policyポリシーライセンス公開

6882 ワード

交流QQ群:555913397何か問題があったら、みんなと一緒に交流しましょう.

前回core 3.1のカスタムライセンスhandlerを探りましたが、今回は独自のPolicyポリシーライセンスを試してみましょう。くだらないことは言わないで、すべてコードの中にあります。


ストレージライセンスのプロパティクラスを作成する

namespace CoreMvc.Utinity.Models
{
    /// 
    ///    
    /// 
    public class PermissionItem
    {
        /// 
        ///     
        /// 
        public virtual string Name { get; set; }
        /// 
        ///      
        /// 
        public virtual string ControllerName { get; set; }
        /// 
        ///     
        /// 
        public virtual string ActionName { get; set; }
    }
}

ライセンス情報を格納するキャッシュクラス

using System.Collections.Generic;
using CoreMvc.Utinity.Models;

namespace CoreMvc.Utinity
{
    public class PermissionDictionary
    {
        private static Dictionary> dictionary = new Dictionary>();
        public static void Add(string name, List permissionItems)
        {
            if (null == dictionary.GetValueOrDefault(name))
            {
                dictionary.Add(name, permissionItems);
            }
        }

        public static List Get(string name)
        {
            return dictionary.GetValueOrDefault(name, null);
        }
    }
}

ライセンス条件の作成

using System;
using Microsoft.AspNetCore.Authorization;

namespace CoreMvc.Utinity.Authentications.Requirement
{
    /// 
    ///     
    /// 
    public class PermissionRequirement : IAuthorizationRequirement
    {
        public string DeniedAction { get; set; }
        public string LoginPath { get; set; }
        public string ClaimType { get; set; }
        public TimeSpan Expiration { get; set; }
        public PermissionRequirement(string deniedAction, string loginPath, string claimType, TimeSpan expiration)
        {
            DeniedAction = deniedAction;
            LoginPath = loginPath;
            ClaimType = claimType;
            Expiration = expiration;
        }
    }
}

ライセンスHandler

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreMvc.Utinity.Authentications.Requirement;
using CoreMvc.Utinity.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;

namespace CoreMvc.Utinity.Authentications
{
    public class PermissionAuthnenticationHandler : AuthorizationHandler
    {
        public IAuthenticationSchemeProvider Scheme;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public PermissionAuthnenticationHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            //.net core 3    endpoint ,          
            if (context.Resource is Endpoint endpoint)
            {
                var controllActionDesription = endpoint.Metadata.GetMetadata();
                string controllerName = controllActionDesription.RouteValues["Controller"].ToLower();
                string actionName = controllActionDesription.RouteValues["Action"].ToLower();
                context.Succeed(requirement);
                List permissionList = PermissionDictionary.Get(context.User.Identity.Name);
                if (permissionList.Where(w => w.ControllerName == controllerName && w.ActionName == actionName).Count() > 0)
                {
                    //         
                    context.Succeed(requirement);
                }
                else
                {
                    //      
                    context.Fail();
                }
            }
            await Task.CompletedTask;
        }
    }
}

Loginを作成し、Actionはログイン許可を提供する

[AllowAnonymous]
public async Task Login()
{
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List
    {
        new Claim(ClaimTypes.Name, "fqydhk"),
        new Claim(ClaimTypes.MobilePhone, "1315********"),
        new Claim(ClaimTypes.Email,"[email protected]")
    }, CookieAuthenticationDefaults.AuthenticationScheme);
    var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
    //          
    List permissionList = new List();
    permissionList.Add(new PermissionItem() { Role = "fqydhk", ControllName = "home", ActionName = "authorization" });
    PermissionDictionary.Add("fqydhk", permissionList);
    string url = HttpContext.Request.Query["ReturnUrl"].ToString();
    HttpContext.Response.Redirect(url);
    return View();
}

アクセスするには権限が必要なactionを作成します

[Authorize(Policy = "permission")]
public IActionResult Authorization()
{
    ViewBag.Name = HttpContext.User.Identity.Name ?? "   ,   ";
    return View();
}

次はStartupの中の重さです。csのConfigureServices(IServiceCollection services)は、次のコードを追加します。

PermissionRequirement permissionRequirement = new PermissionRequirement(
        deniedAction: "/home/denied",
        loginPath: "/home/login",
        claimType: ClaimTypes.Name,
        TimeSpan.FromSeconds(60 * 5));
    //      
    services.AddAuthorization(options =>
    {
        //      
        options.AddPolicy("Permission", policy =>
            {
                policy.Requirements.Add(permissionRequirement);
            });
        //      
    }).AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //  cookie  
    }).AddCookie(options =>
    {
        options.LoginPath = new PathString("/home/login");
        options.AccessDeniedPath = new PathString("/home/denied");
        options.ClaimsIssuer = "Cookie";
    });

スタータープでcsのConfigure(IApplicationBuilder app,IWebHostEnvironment env)にイネーブル許可を追加することは、非常に重要です。これは小さな穴です。


            app.UseAuthentication();

            app.UseAuthorization();

            app.UseCookiePolicy();

ここではすべての構成が完了しました。何か質問があれば、伝言やグループディスカッションを歓迎します。