Nancy之Forms验证

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

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

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

User.cs

using Nancy.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TestSelfHostWeb
{
    public class User : IUserIdentity
    {
        public User()
        {
        }
        public User(string userName)
        {
            UserName = userName;
        }
        /// <summary>
        /// 实现接口的成员
        /// </summary>
        public string UserName
        {
            get;
            set;
        }
 
        public string Password
        {
            get;
            set;
        }
 
        public string Role
        {
            get;
            set;
        }
        /// <summary>
        /// 这个是Nancy授权中必须的
        /// </summary>
        public Guid GUID
        {
            get;
            set;
        }
        /// <summary>
        /// 实现接口的成员
        /// </summary>
        public IEnumerable<string> Claims
        {
            get;
            set;
        }
    }
}

UserMapper.cs

using Nancy.Authentication.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using Nancy;
using Nancy.Security;
 
namespace TestSelfHostWeb
{
    class UserMapper : IUserMapper
    {
        //这个用户集合可以来自数据库
        static List<User> _users;
        static UserMapper()
        {
            //初始化验用户数据
            _users = new List<User>();
            _users.Add(new User() { UserName = "aaa", Password = "111111", GUID = new Guid("33e67c06-ed6e-4bd7-a5b0-60ee0fea890c"), Role = "admin" });
            _users.Add(new User() { UserName = "bbb", Password = "222222", GUID = new Guid("fba4be7d-25af-416e-a641-a33174f435d1"), Role = "user" });
        }
        /// <summary>
        /// 实现接口的成员,获取用户的角色,以便验证授权
        /// </summary>
        /// <param name="identifier"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
        {
 
            var user = _users.FirstOrDefault(u => u.GUID == identifier);
            return user == null
                         ? null
                         : new User(user.UserName) { Claims = new string[] { user.Role } };
        }
        /// <summary>
        /// 验证用户,验证成功返回用户的GUID,这是规定
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static Guid? ValidateUser(string userName, string password)
        {
            var user = _users.FirstOrDefault(u => u.UserName == userName && u.Password == password);
 
            if (user == null)
            {
                return null;
            }
            return user.GUID;
        }
    }
}

Bootstrapper.cs

using Nancy;
using Nancy.Bootstrapper;
using Nancy.TinyIoc;
using Nancy.Authentication.Forms;

namespace TestSelfHostWeb
{
    public class Bootstrapper : DefaultNancyBootstrapper
    {
        protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
        {
            base.RequestStartup(container, pipelines, context);
            //验证配置文件
            var formsAuthConfiguration = new FormsAuthenticationConfiguration()
            {
                RedirectUrl = "~/login",//无验证跳转的路由
                UserMapper = container.Resolve<IUserMapper>()//用户对应的Mapper
            };
            //开启验证
            FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
 
        }
    }
}

Login.cs

using Nancy;
using Nancy.Authentication.Forms;
using Nancy.ModelBinding;
using System;
 namespace TestSelfHostWeb.Modules
{
    public class LoginModule : NancyModule
    {
        public LoginModule()
        {
            Get["/login"] = parameters =>
            {
                //用户名和密码验证失败的标识
                ViewBag["error"] = Request.Query.error;
                return View["login"];
            };
 
            Post["/login"] = parameters =>
              {
 
                  var user = this.Bind<User>();
 
                 var guid= UserMapper.ValidateUser(user.UserName, user.Password);
 
                  if (guid == null)
                  {
                      //按用户名密码查询不到时作的标识
                      return this.LogoutAndRedirect("~/login?error=true");
                  }
                  DateTime? expiry = null;
                  //登录后跳转页面,必需用户的GUID
                  return this.LoginAndRedirect(guid.Value, expiry);
                 
              };
        }
    }
}

login.cshtml

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<TestSelfHostWeb.User>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Login</title>
    <style type="text/css">
        body {
            text-align: center;
        }
    </style>
</head>
<body>
    <form action="\Login" method="post">
        UserName:<input id="UserName" name="UserName" type="text" />
        Password:<input id="Password" name="Password" type="password" />
        <input type="submit" value="Login" />
        @if (ViewBag["error"])
        {
            <font color="red">check username or password please</font>
        }
    </form>
</body>
</html>

Index.cs

using Nancy;
using Nancy.Security;
 namespace TestSelfHostWeb.Modules
{
    public class IndexModule : NancyModule
    {
        public IndexModule()
        {
            //开启全局验证
            this.RequiresAuthentication();
            Get["/"] = parameters =>
            {
                //开启角色验证,只有该角色可以访问本路由
                this.RequiresClaims("admin");
                return View["index"];
            };
        }
    }
}

Index.cshtml同上篇的indexx.cshtml

到了test的时刻了

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

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

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

如果用户名密码正确:

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

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

时间: 2024-10-12 05:34:30

Nancy之Forms验证的相关文章

asp.net中使用基于角色role的Forms验证

http://www.cnblogs.com/yao/archive/2006/06/24/434783.html asp.net中使用基于角色role的Forms验证,大致经过几下四步:1.配置系统web.config system.web> <authentication mode="Forms" >  <forms name=".yaoCookies" loginUrl="/duan/Manage/login.aspx&quo

asp.net中使用forms验证

1.首先在web.config中修改验证方式为 "Forms" <authentication mode="Forms"> 这里的模式有很多中,可自己去百度 2.在<authentication mode="Forms"></authentication>中添加: <forms name="loginAuth" protection="All" loginUrl=&

当ASP.NET Forms验证方式遭遇苹果IOS

一.问题出现 我在用ASP.NET MVC4做微信开发的时候,用Forms验证方式做为authentication. 一般都是在web.config加: <authentication mode="Forms" > <forms loginUrl="~/Account/Login" name="webcookies" slidingExpiration="true" timeout="30"

.net高手:forms验证中中&lt;forms loginUrl=&quot;&quot; defaultUrl=&quot;&quot;&gt;defaulturl和loginurl的区别

.net高手:forms验证中中<forms  loginUrl="" defaultUrl="">defaulturl和loginurl的区别 defaulturl是指你正确登录了后,在没有指向页的时候跳到的页面.Loginurl是指用户没有登录,跳到的登录页面. 打个比方,现在一个客户没有登录想进管理,那就会跳到loginurl. 如果你直接进入的登录,也就是说在没有发生任何错误时直接登录,登录成功后你总要有个提示或跳到哪个页面,那个页面就可以在De

Forms验证在Web.config中的配置说明

<forms name="name" loginUrl="URL" defaultUrl="URL" protection="[All|None|Encryption|Validation]" timeout="[MM]" path="path" requireSSL="[true|false]" slidingExpiration="[true|fa

简单的forms验证

public class CustomAuthorzieAttribute : AuthorizeAttribute { private string _controllerName = string.Empty; /// <summary> /// base.OnAuthorization(filterContext)中会调用AuthorizeCore函数 /// 当AuthorizeCore返回false,则会继续调用HandleUnauthorizedRequest进行处理 /// 所以

asp.net Forms身份验证详解

在做网站的时候,都会用到用户登录的功能.对于一些敏感的资源,我们只希望被授权的用户才能够访问,这让然需要用户的身份验证.对于初学者,通常将用户登录信息存放在Session中,笔者在刚接触到asp.net的时候就是这么做的.当我将用户信息存在在Session中时,常常会遇到Session丢失导致用户无法正常访问被授权的资源,保持用户登录状态时的安全性问题,无休止的将用户导航到登录页面等莫名其妙的问题. 其实,在asp.net中,我们有更好的解决方案,那就是通过Forms身份验证,从而对用户进行授权

两系统用asp.net forms 身份验证方式实现跨域登录信息共享

1.两个系统的 web.config 都配置为 forms 验证方式( system.web —> authentication 节点) 2.在两个系统的Web.config里配置相同的 system.web —> machineKey 节点(节点生成:http://www.aspnetresources.com/tools/keycreator.aspx) 3.在两个系统的Web.config里配置相同的 system.web —> httpCookies 节点(<httpCoo

asp.net forms 表单验证 实现跨域共享cookie(即SSO,单点登录(在二级域名下))

1.前提: 需要做一个单点登录,使用asp.net自带的表单验证(FormsAuthentication) 配置文件怎么写,如下(基本的): <authentication mode="Forms"> <forms loginUrl="~/user/login" enableCrossAppRedirects="true" timeout="3600" name="qz.bbs" cook