關於 DotNetCore 的自定義權限管理


 

1、自定義權限需要擴展 Microsoft.AspNetCore.Authentication 實現一套接口

IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler

   public class MyAuthenticationHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
    {
        public AuthenticationScheme Scheme { get; private set; }
        protected HttpContext Context { get; private set; }

        public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
        {
            Scheme = scheme;
            Context = context;
            return Task.CompletedTask;
        }

        public Task ChallengeAsync(AuthenticationProperties properties)
        {
            Context.Response.Redirect("/Account/login");
            return Task.CompletedTask;
        }

        public async Task<AuthenticateResult> AuthenticateAsync()
        {
            var result = await Task.Run<AuthenticateResult>(() =>
            {
                var cookie = Context.Request.Cookies["myCookie"];
                if (string.IsNullOrEmpty(cookie))
                {
                    return AuthenticateResult.NoResult();
                }
                return AuthenticateResult.Success(this.Deserialize(cookie));
            });

            return result;
        }


        public Task ForbidAsync(AuthenticationProperties properties)
        {
            Context.Response.StatusCode = 403;
            return Task.CompletedTask;
        }

        public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
        {
            var ticket = new AuthenticationTicket(user, properties, Scheme.Name);
            Context.Response.Cookies.Append("myCookie", Serialize(ticket));
            return Task.CompletedTask;
        }

        public Task SignOutAsync(AuthenticationProperties properties)
        {
            Context.Response.Cookies.Delete("myCookie");
            return Task.CompletedTask;
        }

        private string Serialize(AuthenticationTicket ticket)
        {
            byte[] byteTicket = TicketSerializer.Default.Serialize(ticket);
            return System.Text.Encoding.Default.GetString(byteTicket);
        }

        private AuthenticationTicket Deserialize(string ticket)
        {
            byte[] byteTicket = System.Text.Encoding.Default.GetBytes(ticket);
            return TicketSerializer.Default.Deserialize(byteTicket);
        }
    }

 

2、在 ConfigureServices 中注冊服務

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(
               option =>
               {
                   option.DefaultScheme = "myScheme";
                   option.AddScheme<MyAuthenticationHandler>("myScheme", "demo scheme");
               });

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSession();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

 

3、在 void Configure(IApplicationBuilder app, IHostingEnvironment env) 中使用權限檢查

app.UseAuthentication();

 

4、在 Controller 中實現自己的 Login 、Logout 

       [AllowAnonymous]
        public async void Login(string username, string password)
        {
            var claimIdentity = new ClaimsIdentity("CustomApiKeyAuth");
            claimIdentity.AddClaim(new Claim(ClaimTypes.Name, username));
            claimIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));
            await HttpContext.SignInAsync("myScheme", new ClaimsPrincipal(claimIdentity));
            await HttpContext.Response.WriteAsync($"Hello {username} login!");
        }

        public async void Logout()
        {
            await HttpContext.SignOutAsync("myScheme");
        }

 

5、在 Controller 中使用權限檢查特性

       [Authorize(Roles = "Admin")]
        public void Test()
        {
            var user = HttpContext.User;
            HttpContext.Response.WriteAsync($"Test {user.Identity.Name}!");
        }

 

6、測試

   在瀏覽器上輸入 https://localhost:44318/account/login?username="aaa"

       系統輸出: Hello "aaa" login!

  在瀏覽器上輸入 https://localhost:44318/account/test

       系統輸出 : Test "aaa"!

成功運行了。

 

7、結束語

    雖然只是簡單的框架代碼,但實現了完整的流程控制。方便初學者。

   需要源代碼的朋友點這里下載

 

8、參考資料

ASP.NET Core 2.0 authentication middleware

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM