Asp.net Vnext 中间件实现基本验证
概述
本文已经同步到《Asp.net Vnext 系列教程 》中]
vnext 没有 web.config 可以配置基本验证,本文使用中间件实现基本验证
实现
通过Startup(启动类)Configure 方法加入中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory) { app.UseMyMiddleware();
//通过扩展注册中间件 public static class BasicAuthenticationExtensions { public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder app) { return app.UseMiddleware<BasicAuthentication>(); } }
//中间件类 public class BasicAuthentication { private readonly RequestDelegate next; public BasicAuthentication(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context, IAuthenticationService authenticationService) { try { var parser = new BasicAuthenticationParser(context); var username = parser.GetUsername(); var password = parser.GetPassword(); await authenticationService.AuthenticateAsync(username, password); await next(context); } catch (Exception e) { context.Response.StatusCode = 401; context.Response.Headers.Add("WWW-Authenticate", new[] { "Basic" }); } } }
//解析上下文获取 密码 用户名 internal class BasicAuthenticationParser { private readonly string credentials; public BasicAuthenticationParser(HttpContext context) { credentials = GetCredentials(context); } public string GetUsername() { return GetValue(credentials, 0); } public string GetPassword() { return GetValue(credentials, 1); } private static string GetValue(string credentials, int index) { if (string.IsNullOrWhiteSpace(credentials)) return null; var parts = credentials.Split(':'); return parts.Length == 2 ? parts[index] : null; } private static string GetCredentials(HttpContext context) { try { string[] authHeader; if (context.Request.Headers.TryGetValue("Authorization", out authHeader) && authHeader.Any() && authHeader[0].StartsWith("Basic ")) { var value = Convert.FromBase64String(authHeader[0].Split(' ')[1]); return Encoding.UTF8.GetString(value); } return null; } catch { return null; } } }
//认证服务接口 public interface IAuthenticationService { Task AuthenticateAsync(string username, string password); } public class SimpleAuthenticationService : IAuthenticationService { public Task AuthenticateAsync(string username, string password) { //判读密码 if ("123".Equals(username, StringComparison.OrdinalIgnoreCase) && "123".Equals(password)) { return Task.FromResult(0); } throw new Exception(); } }
运行效果