(精华)2020年9月19日 ASP.NET Core 认证授权详解

Session的使用

public static class Sample01
    {
        public static void Start()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .ConfigureServices(collection => collection
                        .AddDistributedMemoryCache()
                        .AddSession())
                    .Configure(app => app
                        .UseSession()
                        .Run(ProcessAsync)))
                .Build()
                .Run();

            static async Task ProcessAsync(HttpContext context)
            {
                var session = context.Session;
                await session.LoadAsync();
                string sessionStartTime;

                if (session.TryGetValue("SessionStartTime", out var value))
                {
                    sessionStartTime = Encoding.UTF8.GetString(value);
                }
                else
                {
                    sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                    session.SetString("SessionStartTime", sessionStartTime);
                }

                context.Response.ContentType = "text/html";
                await context.Response.WriteAsync($"<html><body><ul><li>Session ID:{session.Id}</li>");
                await context.Response.WriteAsync($"<li>Session Start Time:{sessionStartTime}</li>");
                await context.Response.WriteAsync($"<li>Current Time:{DateTime.Now}</li></ul></table></body></html>");
            }
        }
    }
public static class Sample02
    {
        public static void Start()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .ConfigureServices(collection => collection
                        .AddDistributedMemoryCache()
                        .AddSession())
                    .Configure(app => app
                        .UseSession()
                        .Run(ProcessAsync)))
                .Build()
                .Run();

            static async Task ProcessAsync(HttpContext context)
            {
                var session = context.Session;
                await session.LoadAsync();
                string sessionStartTime;

                if (session.TryGetValue("SessionStartTime", out var value))
                {
                    sessionStartTime = Encoding.UTF8.GetString(value);
                }
                else
                {
                    sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                    session.SetString("SessionStartTime", sessionStartTime);
                }

                // 使用反射获取Session Key
                var field = typeof(DistributedSession).GetTypeInfo().GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
                var sessionKey = field?.GetValue(session);

                context.Response.ContentType = "text/html";
                await context.Response.WriteAsync($"<html><body><ul><li>Session ID:{session.Id}</li>");
                await context.Response.WriteAsync($"<li>Session Key:{sessionKey}</li>");
                await context.Response.WriteAsync($"<li>Session Start Time:{sessionStartTime}</li>");
                await context.Response.WriteAsync($"<li>Current Time:{DateTime.Now}</li></ul></table></body></html>");
            }
        }
    }

Cookie的使用

class Program
    {
        private static readonly Dictionary<string, string> Accounts = new Dictionary<string, string>
        {
            {"Admin", "123"}, {"UserA", "123"}, {"UserB", "123"}
        };

        public static void Main(string[] args)
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .ConfigureServices(collection => collection
                        .AddRouting()
                        .AddAuthentication(options =>
                            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme)
                        .AddCookie())
                    .Configure(app => app
                        .UseAuthentication()
                        .UseRouting()
                        .UseEndpoints(endpoints =>
                        {
                            endpoints.Map("/", RenderHomePageAsync);
                            endpoints.Map("Account/Login", SignInAsync);
                            endpoints.Map("Account/Logout", SignOutAsync);
                        })))
                .Build()
                .Run();
        }

        public static async Task RenderHomePageAsync(HttpContext context)
        {
            if (context?.User?.Identity?.IsAuthenticated == true)
            {
                await context.Response.WriteAsync(
                    @"<html>
                    <head><title>Index</title></head>
                    <body>" +
                    $"<h3>Welcome {context.User.Identity.Name}</h3>" +
                    @"<a href='/Account/Logout'>Sign Out</a>
                    </body>
                </html>");
            }
            else
            {
                await context.ChallengeAsync();
            }
               
        }


        public static async Task SignInAsync(HttpContext context)
        {
            if (string.CompareOrdinal(context.Request.Method, "GET") == 0)
            {
                await RenderLoginPageAsync(context, null, null, null);
            }
            else
            {
                var userName = context.Request.Form["username"];
                var password = context.Request.Form["password"];
                if (Accounts.TryGetValue(userName, out var pwd) && pwd == password)
                {
                    var identity = new GenericIdentity(userName, "Passord");
                    var principal = new ClaimsPrincipal(identity);
                    await context.SignInAsync(principal);
                }
                else
                {
                    await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
                }
            }
        }

        private static Task RenderLoginPageAsync(HttpContext context, string userName, string password,
            string errorMessage)
        {
            context.Response.ContentType = "text/html";
            return context.Response.WriteAsync(
                @"<html>
                <head><title>Login</title></head>
                <body>
                    <form method='post'>" +
                $"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
                $"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
                @"<input type='submit' value='Sign In' />
                    </form>" +
                $"<p style='color:red'>{errorMessage}</p>" +
                @"</body>
            </html>");
        }


        public static async Task SignOutAsync(HttpContext context)
        {
            await context.SignOutAsync();
            context.Response.Redirect("/");
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .ConfigureServices(collection => collection
                        .AddDbContext<UserDbContext>(options => options
                            .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=AuthorizationDemo;Trusted_Connection=True;MultipleActiveResultSets=true")
                        )
                        .AddRouting()
                        .AddAuthorization()
                        .AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme).AddCookie())
                    .Configure(app => app
                        .UseAuthentication()
                        .UseRouting()
                        .UseEndpoints(endpoints =>
                        {
                            endpoints.Map("/", RenderHomePageAsync);
                            endpoints.Map("Account/Login", SignInAsync);
                            endpoints.Map("Account/Logout", SignOutAsync);
                            endpoints.Map("Account/AccessDenied", DenyAccessAsync);
                        })))
                .Build()
                .Run();
        }

        public static async Task RenderHomePageAsync(HttpContext context)
        {
            if (context?.User?.Identity?.IsAuthenticated == true)
            {
                var requirement = new RolesAuthorizationRequirement(new [] { "ADMIN" });
                var authorizationService = context.RequestServices.GetRequiredService<IAuthorizationService>();
                var result = await authorizationService.AuthorizeAsync(context.User, null, new IAuthorizationRequirement[] { requirement });
                if (result.Succeeded)
                {
                    await context.Response.WriteAsync(
                        @"<html>
                    <head><title>Index</title></head>
                    <body>" +
                        $"<h3>{context.User.Identity.Name}, you are authorized.</h3>" +
                        @"<a href='Account/Logout'>Sign Out</a>
                    </body>
                </html>");
                }
                else
                {
                    await context.ForbidAsync();
                }
            }
            else
            {
                await context.ChallengeAsync();
            }
        }

          public static async Task SignInAsync(HttpContext context)
        {
            if (string.Compare(context.Request.Method, "GET") == 0)
            {
                await RenderLoginPageAsync(context, null, null, null);
            }
            else
            {
                string userName = context.Request.Form["username"];
                string password = context.Request.Form["password"];
                var dbContext = context.RequestServices.GetRequiredService<UserDbContext>();
                var user = await dbContext.Users.Include(it => it.Roles).SingleOrDefaultAsync(it => it.UserName == userName.ToUpper());
                if (user?.Password == password)
                {
                    var identity = new GenericIdentity(userName, CookieAuthenticationDefaults.AuthenticationScheme);
                    foreach (var role in user.Roles)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Role, role.NormalizedRoleName));
                    }
                    var principal = new ClaimsPrincipal(identity);
                    await context.SignInAsync(principal);
                }
                else
                {
                    await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
                }
            }
        }

        private static Task RenderLoginPageAsync(HttpContext context, string userName, string password, string errorMessage)
        {
            context.Response.ContentType = "text/html";
            return context.Response.WriteAsync(
                @"<html>
                <head><title>Login</title></head>
                <body>
                    <form method='post'>" +
                            $"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
                            $"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
                            @"<input type='submit' value='Sign In' />
                    </form>" +
                            $"<p style='color:red'>{errorMessage}</p>" +
                    @"</body>
            </html>");
        }

        public static async Task SignOutAsync(HttpContext context)
        {
            await context.SignOutAsync();
            await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
        }

        public static Task DenyAccessAsync(HttpContext context)
        {
            return context.Response.WriteAsync(
                @"<html>
                <head><title>Index</title></head>
                <body>" +
                $"<h3>{context.User.Identity.Name}, your access is denied.</h3>" +
                @"<a href='/Account/Logout'>Sign Out</a>
                </body>
            </html>");
        } 

      
    }

CookieAuthentication

class Program
    {
        static void Main(string[] args)
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .ConfigureServices(collection => collection
                        .AddDbContext<UserDbContext>(options => options
                            .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=AuthorizationDemo;Trusted_Connection=True;MultipleActiveResultSets=true")
                        )
                        .AddRouting()
                        .AddAuthorization(options => {
                            var requirement = new RolesAuthorizationRequirement(new [] { "ADMIN" });
                            var policy = new AuthorizationPolicy(new IAuthorizationRequirement[] { requirement }, new string[0]);
                            options.AddPolicy("HomePage", policy);
                        })
                        .AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme).AddCookie())
                    .Configure(app => app
                        .UseAuthentication()
                        .UseRouting()
                        .UseEndpoints(endpoints =>
                        {
                            endpoints.Map("/", RenderHomePageAsync);
                            endpoints.Map("Account/Login", SignInAsync);
                            endpoints.Map("Account/Logout", SignOutAsync);
                            endpoints.Map("Account/AccessDenied", DenyAccessAsync);
                        })))
                .Build()
                .Run();
        }

        public static async Task RenderHomePageAsync(HttpContext context)
        {
            if (context?.User?.Identity?.IsAuthenticated == true)
            {
                var authorizationService = context.RequestServices.GetRequiredService<IAuthorizationService>();
                var result = await authorizationService.AuthorizeAsync(context.User, "HomePage");
                if (result.Succeeded)
                {
                    await context.Response.WriteAsync(
                        @"<html>
                    <head><title>Index</title></head>
                    <body>" +
                        $"<h3>{context.User.Identity.Name}, you are authorized.</h3>" +
                        @"<a href='Account/Logout'>Sign Out</a>
                    </body>
                </html>");
                }
                else
                {
                    await context.ForbidAsync();
                }
            }
            else
            {
                await context.ChallengeAsync();
            }
        }

          public static async Task SignInAsync(HttpContext context)
        {
            if (string.Compare(context.Request.Method, "GET") == 0)
            {
                await RenderLoginPageAsync(context, null, null, null);
            }
            else
            {
                string userName = context.Request.Form["username"];
                string password = context.Request.Form["password"];
                var dbContext = context.RequestServices.GetRequiredService<UserDbContext>();
                var user = await dbContext.Users.Include(it => it.Roles).SingleOrDefaultAsync(it => it.UserName == userName.ToUpper());
                if (user?.Password == password)
                {
                    var identity = new GenericIdentity(userName, CookieAuthenticationDefaults.AuthenticationScheme);
                    foreach (var role in user.Roles)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Role, role.NormalizedRoleName));
                    }
                    var principal = new ClaimsPrincipal(identity);
                    await context.SignInAsync(principal);
                }
                else
                {
                    await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
                }
            }
        }

        private static Task RenderLoginPageAsync(HttpContext context, string userName, string password, string errorMessage)
        {
            context.Response.ContentType = "text/html";
            return context.Response.WriteAsync(
                @"<html>
                <head><title>Login</title></head>
                <body>
                    <form method='post'>" +
                            $"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
                            $"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
                            @"<input type='submit' value='Sign In' />
                    </form>" +
                            $"<p style='color:red'>{errorMessage}</p>" +
                    @"</body>
            </html>");
        }

        public static async Task SignOutAsync(HttpContext context)
        {
            await context.SignOutAsync();
            await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
        }

        public static Task DenyAccessAsync(HttpContext context)
        {
            return context.Response.WriteAsync(
                @"<html>
                <head><title>Index</title></head>
                <body>" +
                $"<h3>{context.User.Identity.Name}, your access is denied.</h3>" +
                @"<a href='/Account/Logout'>Sign Out</a>
                </body>
            </html>");
        } 

      
    }

权限认证交互示例

public class Program
    {
        public static void Main()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .UseUrls("http://*:443")
                    
                    .Configure(app => app.Run(ProcessAsync)))
                .Build()
                .Run();

            static async Task ProcessAsync(HttpContext httpContext)
            {
                httpContext.Response.ContentType = "text/html";
                var html =
                @"<html>
                <body>
                    <ul id='contacts'></ul>
                    <script src='http://code.jquery.com/jquery-3.3.1.min.js'></script>
                    <script>
                    $(function()
                    {
                        var url = 'http://www.one.com:8080/contacts';
                        $.getJSON(url, null, function(contacts) {
                            $.each(contacts, function(index, contact)
                            {
                                var html = '<li><ul>';
                                html += '<li>Name: ' + contact.Name + '</li>';
                                html += '<li>Phone No:' + contact.PhoneNo + '</li>';
                                html += '<li>Email Address: ' + contact.EmailAddress + '</li>';
                                html += '</ul>';
                                $('#contacts').append($(html));
                            });
                        });
                    });
                    </script >
                </body>
                </html>";
                await httpContext.Response.WriteAsync(html);
            }
        }
    }
public class Program
    {
        public static void Main()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder => builder
                    .UseUrls("http://*:8080")
                    .Configure(app => app
                        .UsePathBase("/contacts")
                        .Run(ProcessAsync)))
                .Build()
                .Run();

            static Task ProcessAsync(HttpContext httpContext)
            {
                var response = httpContext.Response;
                response.ContentType = "application/json";
                var contacts = new Contact[]
                {
                new Contact("张三", "123", "zhangsan@qq.com"),
                new Contact("李四","456", "lisi@qq.com"),
                new Contact("王五", "789", "wangwu@qq.com")
                };
                return response.WriteAsync(JsonConvert.SerializeObject(contacts));
            }
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚公搬代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值