授权几乎是所以系统都不可或缺的部分,在Nancy中怎么授权呢?我们这篇博文来说一下Nancy的Forms授权。

首先在NuGet上安装Nancy.Authentication.Forms

Nancy的Forms验证得实现IUserMapper接口,用户类实现IUserIdentity接口(为了方便,我把DB的User,Model的User全合成一个User)

User.cs

usingNancy.Security;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceTestSelfHostWeb{publicclassUser:IUserIdentity{publicUser(){}publicUser(stringuserName){UserName=userName;}///<summary>///实现接口的成员///</summary>publicstringUserName{get;set;}publicstringPassword{get;set;}publicstringRole{get;set;}///<summary>///这个是Nancy授权中必须的///</summary>publicGuidGUID{get;set;}///<summary>///实现接口的成员///</summary>publicIEnumerable<string>Claims{get;set;}}}


UserMapper.cs

usingNancy.Authentication.Forms;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingNancy;usingNancy.Security;namespaceTestSelfHostWeb{classUserMapper:IUserMapper{//这个用户集合可以来自数据库staticList<User>_users;staticUserMapper(){//初始化验用户数据_users=newList<User>();_users.Add(newUser(){UserName="aaa",Password="111111",GUID=newGuid("33e67c06-ed6e-4bd7-a5b0-60ee0fea890c"),Role="admin"});_users.Add(newUser(){UserName="bbb",Password="222222",GUID=newGuid("fba4be7d-25af-416e-a641-a33174f435d1"),Role="user"});}///<summary>///实现接口的成员,获取用户的角色,以便验证授权///</summary>///<paramname="identifier"></param>///<paramname="context"></param>///<returns></returns>publicIUserIdentityGetUserFromIdentifier(Guididentifier,NancyContextcontext){varuser=_users.FirstOrDefault(u=>u.GUID==identifier);returnuser==null?null:newUser(user.UserName){Claims=newstring[]{user.Role}};}///<summary>///验证用户,验证成功返回用户的GUID,这是规定///</summary>///<paramname="userName"></param>///<paramname="password"></param>///<returns></returns>publicstaticGuid?ValidateUser(stringuserName,stringpassword){varuser=_users.FirstOrDefault(u=>u.UserName==userName&&u.Password==password);if(user==null){returnnull;}returnuser.GUID;}}}

Bootstrapper.cs

usingNancy;usingNancy.Bootstrapper;usingNancy.TinyIoc;usingNancy.Authentication.Forms;namespaceTestSelfHostWeb{publicclassBootstrapper:DefaultNancyBootstrapper{protectedoverridevoidRequestStartup(TinyIoCContainercontainer,IPipelinespipelines,NancyContextcontext){base.RequestStartup(container,pipelines,context);//验证配置文件varformsAuthConfiguration=newFormsAuthenticationConfiguration(){RedirectUrl="~/login",//无验证跳转的路由UserMapper=container.Resolve<IUserMapper>()//用户对应的Mapper};//开启验证FormsAuthentication.Enable(pipelines,formsAuthConfiguration);}}}

Login.cs

usingNancy;usingNancy.Authentication.Forms;usingNancy.ModelBinding;usingSystem;namespaceTestSelfHostWeb.Modules{publicclassLoginModule:NancyModule{publicLoginModule(){Get["/login"]=parameters=>{//用户名和密码验证失败的标识ViewBag["error"]=Request.Query.error;returnView["login"];};Post["/login"]=parameters=>{varuser=this.Bind<User>();varguid=UserMapper.ValidateUser(user.UserName,user.Password);if(guid==null){//按用户名密码查询不到时作的标识returnthis.LogoutAndRedirect("~/login?error=true");}DateTime?expiry=null;//登录后跳转页面,必需用户的GUIDreturnthis.LoginAndRedirect(guid.Value,expiry);};}}}


login.cshtml

@inheritsNancy.ViewEngines.Razor.NancyRazorViewBase<TestSelfHostWeb.User><!DOCTYPEhtml><htmllang="en"><head><metacharset="utf-8"/><title>Login</title><styletype="text/css">body{text-align:center;}</style></head><body><formaction="\Login"method="post">UserName:<inputid="UserName"name="UserName"type="text"/>Password:<inputid="Password"name="Password"type="password"/><inputtype="submit"value="Login"/>@if(ViewBag["error"]){<fontcolor="red">checkusernameorpasswordplease</font>}</form></body></html>


Index.cs

usingNancy;usingNancy.Security;namespaceTestSelfHostWeb.Modules{publicclassIndexModule:NancyModule{publicIndexModule(){//开启全局验证this.RequiresAuthentication();Get["/"]=parameters=>{//开启角色验证,只有该角色可以访问本路由this.RequiresClaims("admin");returnView["index"];};}}}


Index.cshtml同上篇的indexx.cshtml

到了test的时刻了

启动host(注意以管理员身份运行)

访问网站的主页,如下图,会跳转到登记页,这是因为index.cs的IndexModule中开启了this.RequiresAuthentication()验证,为什么会跳转到login路由中呢,是因为Bootstrapper中formAuthConfiguration中的RedirectUrl设置。

如果用户名或密码错误 ,会得到提示:

如果用户名密码正确:

如果不具备权限的人(UserName:bbb,Passowrd:222222)登录,会报403错误(这个不太友下,下篇博客解决)

这样就能轻量级的按解色来授权我们的系统了。