怎么做网站上翻译泰剧,app需要申请网站的子域名吗,企业手机网站建设联系方式,快速排名程序我们现在大多数转向ASP.NET Core来使用开发的团队#xff0c;应该都不是从0开始搭建系统#xff0c;而是老的业务系统已经在运行#xff0c;ASP.NET Core用来开发新模块。那么解决用户认证的问题#xff0c;成为我们的第一个拦路虎。 认证与授权 什么是认证#xff1f; … 我们现在大多数转向ASP.NET Core来使用开发的团队应该都不是从0开始搭建系统而是老的业务系统已经在运行ASP.NET Core用来开发新模块。那么解决用户认证的问题成为我们的第一个拦路虎。 认证与授权 什么是认证 首先认证并不是登录。认证是一个知道用户是谁的一个过程。我们最早使用的基于Session的认证拿到用户输入的用户名和密码到数据库里面校验一看看是否正确如果是正确的我们就放到session里面。这是一个完成认证的过程系统现在知道你是我的某一个用户了。 那么何谓授权 现在用户登录之后我们跳转到了另一个页面这个页面可能会写一段这样的代码。 if(Session[user]null)
{Response.redirect(/login.aspx)
} 如果用户登录的Session不存在则再跳回到登录页面让用户登录。 检查当前用户有没有某个权限的这个过程叫授权。如果没有怎么办我们就会跳转用户到一个没有权限的提示页面或者返回 Forbidden 403 的HTTP 状态码这是最简单的授权。 复杂的授权方式包括对角色对具体资源访问以及操作的授权这块我们后面再讲。 当我们的ASP.NET Core项目需要与老的项目兼容的时候就需要兼容老项目的认证方式比如某种自定义的token这是之前比较常见的做法。我们需要在ASP.NET Core中根据当前用户header里面的token来判断是否为一个合法的用户。 用Middleware拦截 第一种简单粗暴的方法即用Middleware来拦截。 在ASP.NET Core下MVC以一个Middleware加入到整个HTTP管道。在此之前还会添加一个Routing的Middleware注意这里的意思也就是说 Routing不再和ASP.NET MVC一样属于它的一部分。正好相反在ASP.NET Core里面是有一个MVCRouteHandler被 Routing Middleware 加载出来处理请求。关于路由这块我们后面再说。 如果我们要在MVC Middleware执行之请拦截请求只要加一个Middleware在 MVC Middleware或者Routing之前即可。 public void Configure(IApplicationBuilder app){app.Use(async (context, next) { if (context.Request.Headers.ContainsKey(token)){ var token context.Request.Headers[token].FirstOrDefault(); if (token jessetalk.cn){ await next();}} context.Response.StatusCode 401;});app.UseMvc();
} 上面是我们有简易的方法实现的一个Middleware被加到了MVC之前。当Request的Headers中没有一个值为“jessetalk.cn” 以及 name为” token”的项的时候我们就返回401状态并且不执行后面的处理。不调用 next方法) 但是这种办法相当于一刀切我们添加的这个Middleware发生在 MVC Middleware之前把所有没有认证信息的请求全部拦截掉了。好处是有节省服务器资源如果确定是要拦截的就没有必须再经过MVC的一些处理了坏处是无法实现单个Controller或者Action的灵活配置。 定制JWTBearer Authentication ASP.NET Core为我们实现了JWTBearer Authentication关于 JWTBearer Authentication的实现可以参考另外一篇文章《在ASP.NET Core中使用JWTBearer Authentication》。我们今天要做的就是通过定制JWTBearer Authentication来达到让它读取我们自定义的Token并且用我们自己的方式来校验这个Token。有点时代倒退的感觉是不是 如果在时间和人员都足够的情况下我们是可能直接整体替换成标准的JWT方案甚至做到SSO。但是架构是没有止境的在一定的时间框架下要做到高效且安全的切换这不失为一种好办法。 首先我们需要看一下在JWTBearer中默认获取的token是在Authorization的头里Bearer空格加上token。而如果有不规范的做法可能是直接在headers里面加了一个token里面有一个用我们自己的算法生成的token。 更改token的来源 JWTBearer authentication handler提供的Events中有一个OnMessageReceived委托可以让我们从另外的地方读取token。 services.AddAuthentication(options
{options.DefaultAuthenticateScheme JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o {o.Events new JwtBearerEvents(){OnMessageReceived context { var token context.Request.Headers[token];context.Token token.FirstOrDefault(); return Task.CompletedTask;},};
}); 定制token的验证方式 从headers里面拿到token之后下一步就是要把它的验证算法改成我们自己的。这一步可以通过自定义 ISecurityTokenValidator来实现 。我们在这个Validator里面校验token生成一个ClaimsPrincipal这个principal就会被赋值到 HttpContext.User上。 同时我们还根据当前的token添加了一个Role Claim它的值有user和admin。这个可能用来做基于角色的授权 。 public class MyTokenValidator : ISecurityTokenValidator{ public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) {validatedToken null; var identity new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);identity.AddClaim(new Claim(name, jesse));identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, securityToken jessetalk.cn ? admin : user)); var principal new ClaimsPrincipal(identity); return principal;}
} 注意ClaimsIdentity的AuthenticationScheme一定要与我们在UseAuthentication时设置的名称一样。否则Identity.IsAuthenticated无法正确设置为true我们的授权就没有办法完成。 有了我们自定义的Validator之后我们要对JwtBearer进行改造去掉它默认的Validator加上我们自己定义的这个。 services.AddAuthentication(options
{options.DefaultAuthenticateScheme JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o
{o.SecurityTokenValidators.Clear();o.SecurityTokenValidators.Add(new MyTokenValidator());
}); 开始进行授权 为了给大家演示上面的功能我们新建两个Controller一个是Admin另一个是Home。两者都需要用户有token才能正常访问但是对于Admin我们需要用户具有admin的role才可以否则会被拒绝返回403。 HomeController.cs [Authorize]public class HomeController : Controller{ public IActionResult Index() { return Ok();}
} 当Headers里面没有token 值的时候API请求返回 401。 当Headers里面有token值时API可以被正常访问。 我们又加了一个AdminController不一样的是这次我们给Authorize加上了Role”admin”也就是只有拥有admin的Role才可以访问这个API。 [Authorize(Roles admin)]public class AdminController : Controller{ public IActionResult Index() { return Ok();}
} 当我们用user的token访问时我们会得到403。 只有用admin的token才能正常访问。 以是就是基于JWT Authentication来定制的我们自己的认证方案的一个基本思路主要是实现OnMessageReceived来改造token的来源以及定义自己的 ISecurityTokenValidator 来实现对token的验证。 原文地址http://www.jessetalk.cn/2017/11/03/asp-net-core-authentication-with-legacy-system/.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com