Nancy之Forms authentication的简单使用
2016-02-17 15:41
323 查看
一、前言
想必大家或多或少都听过微软推出的ASP.NET Identity技术,可以简单的认为就是一种授权的实现很巧的是,Nancy中也有与之相类似的技术Authentication,这两者之间都用到了一些相通的安全技术
(我没有去看ASP.NET Identity的内部实现,是从它的简单用法中判断的)
正式开始介绍之前先推荐几篇ASP.NET Identity的好文章
r01cn 的 ASP.NET Identity系列教程(目录)
腾飞(Jesse) 的 MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN
好了,下面还是用demo的形式来介绍怎么简单使用Forms authentication吧
二、简单使用
1)、新建一个空的asp.net项目
2)、通过NuGet安装相应的包
Install-Package Nancy Install-Package Nancy.Hosting.Aspnet Install-Package Nancy.Authentication.Forms Install-Package Dapper
由于用到了数据库访问,所以还安装了Dapper
3)、建立数据表
CREATE TABLE [dbo].[SystemUser]( [SystemUserId] [uniqueidentifier] NOT NULL, [SystemUserName] [nvarchar](50) NOT NULL, [SystemUserPassword] [nvarchar](50) NOT NULL, CONSTRAINT [PK_SystemUser] PRIMARY KEY CLUSTERED ( [SystemUserId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
同时像表中插入两条数据
INSERT INTO [dbo].[SystemUser]([SystemUserId],[SystemUserName],[SystemUserPassword]) VALUES(newid(),'catcher','123') INSERT INTO [dbo].[SystemUser]([SystemUserId],[SystemUserName],[SystemUserPassword]) VALUES(newid(),'admin','123')
注:由于是演示,所以密码没有进行加密处理
4)、建立相应的文件夹
Models用于存放模型
Modules用于存放相应的操作
Views用于存放视图
5)、编写模型 SystemUser.cs
public class SystemUser { public Guid SystemUserId { get; set; } public string SystemUserName { get; set; } public string SystemUserPassword { get; set; } }
6)、编写HomeModule.cs
using Dapper; using Nancy; using Nancy.Authentication.Forms; using Nancy.ModelBinding; using NancyDemoForFormsauthentication.Models; using System.Data; using System.Data.SqlClient; using System.Linq; namespace NancyDemoForFormsauthentication.Modules { public class HomeModule : NancyModule { public HomeModule() { Get["/"] = _ => { return View["index"]; }; Get["/login"] = _ => { return View["login"]; }; Post["/login"] = _ => { var loginUser = this.Bind<SystemUser>(); SystemUser user = GetValidUser(loginUser.SystemUserName, loginUser.SystemUserPassword); if (user == null) { return Response.AsText("出错了", "text/html;charset=UTF-8"); } return this.LoginAndRedirect(user.SystemUserId, fallbackRedirectUrl: "/secure"); }; } private readonly string sqlconnection = "Data Source=127.0.0.1;Initial Catalog=NancyDemo;User Id=sa;Password=dream_time1314;"; private SqlConnection OpenConnection() { SqlConnection connection = new SqlConnection(sqlconnection); connection.Open(); return connection; } private SystemUser GetValidUser(string name, string pwd) { using (IDbConnection conn = OpenConnection()) { const string query = "select * from SystemUser where SystemUserName=@SystemUserName and SystemUserPassword=@SystemUserPassword"; return conn.Query<SystemUser>(query, new { SystemUserName = name, SystemUserPassword = pwd }).SingleOrDefault(); } } } }
其中,登录的post方法中用到了 LoginAndRedirect 这个静态方法
这个方法位于ModuleExtensions.cs中,返回值是Response类型的
public static Response LoginAndRedirect(this INancyModule module, Guid userIdentifier, DateTime? cookieExpiry = null, string fallbackRedirectUrl = "/") { return FormsAuthentication.UserLoggedInRedirectResponse(module.Context, userIdentifier, cookieExpiry, fallbackRedirectUrl); }
看方法名都能知道这个是用来干什么的!
还有Response.AsText后面的第二个参数可以让中文不乱码!!
7)、编写相应的视图
index.html<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <h2>Nancy之基于Forms authentication的简单使用</h2> <p>访问需要权限的页面</p> <a href="/secure">secure</a> </body> </html>
login.html
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <form method="post" action="/login"> <label>姓名:</label><input type="text" name="SystemUserName" /><br /> <label>密码:</label><input type="password" name="SystemUserPassword" /><br /> <input type="submit" /> </form> </body> </html>
8)、编写SecureModule.cs
using Nancy; using Nancy.Security; namespace NancyDemoForFormsauthentication.Modules { public class SecureModule : NancyModule { public SecureModule() { this.RequiresAuthentication(); Get["/secure"] = _ => { return "Hello ," + this.Context.CurrentUser.UserName; }; } } }
其中
this.RequiresAuthentication();
这句是关键!!表明需要验证才能通过。位于Nancy.Security这个命名空间
通过验证访问后会打印出当前的用户名称。
9)、编写Bootstraper.cs
using Nancy; using Nancy.Authentication.Forms; using Nancy.TinyIoc; using Nancy.Bootstrapper; namespace NancyDemoForFormsauthentication { public class Bootstrapper : DefaultNancyBootstrapper { protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) { base.ConfigureRequestContainer(container, context); container.Register<IUserMapper, UserMapper>(); } 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>(), }; FormsAuthentication.Enable(pipelines, formsAuthConfiguration); } } }
这里是至关重要的一步!!!
要在RequestStartup中启用我们的FormsAuthentication!!
同时我们还要配置FormsAuthenticationConfiguration
注册了UserMapper,所以我们接下来就是实现UserMapper
10)、编写UserMapper.cs
using Dapper; using Nancy; using Nancy.Authentication.Forms; using Nancy.Security; using NancyDemoForFormsauthentication.Models; using System; using System.Data; using System.Data.SqlClient; using System.Linq; namespace NancyDemoForFormsauthentication { public class UserMapper : IUserMapper { public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) { using (IDbConnection conn = OpenConnection()) { const string query = "select * from SystemUser where SystemUserId=@SystemUserId"; var user = conn.Query<SystemUser>(query, new { SystemUserId = identifier }).SingleOrDefault(); if (user == null) { return null; } else { return new UserIdentity { UserName = user.SystemUserName, Claims = new[] { "SystemUser"} }; } } } private readonly string sqlconnection = "Data Source=127.0.0.1;Initial Catalog=NancyDemo;User Id=sa;Password=dream_time1314;"; private SqlConnection OpenConnection() { SqlConnection connection = new SqlConnection(sqlconnection); connection.Open(); return connection; } } }
UserMapper必须要实现IUserMapper这个接口!同时返回一个实现IUserIdentity接口的对象。
11)、编写UserIdentity.cs
using Nancy.Security; using System.Collections.Generic; namespace NancyDemoForFormsauthentication { public class UserIdentity : IUserIdentity { public string UserName { get; set; } public IEnumerable<string> Claims { get; set; } } }
到这里所有的工作都已经做完了,下面就是看看效果了
我们点击 secure链接,发现自动跳转到登录界面了!!
我们输入用户名和密码
登录成功,并返回到secure页面了!
当我们输入错误的用户名和密码时
最后是本次示例代码:
https://github.com/hwqdt/Demos/tree/master/src/NancyDemoForFormsauthentication
相关文章推荐
- 在MainActivity的内部静态类PlaceholderFragment 类中的onCreateView中获取fragment_main.xml中控件
- 计算进位次数
- gerrit添加新用户
- log4j.properties配置详解
- Error: "源代码不可用于此位置"
- 使用jquery获取同组单选框中被选中项的value或给同组单选框赋值
- blog
- 格式化数字
- 【笔记】DOM探索基础篇(二)
- 算法导论值快速排序
- Hibernate反向工程-——Myeclipse从数据库反向生成Java类
- JAVA字符串格式化-String.format()的使用
- CodeSign error: no provisioning profile at path '/Users/user/Library/MobileDevice/Provisioning Profi
- android 屏幕适配之dp
- Openfire 自定义Servlet插件访问Url登录拦截问题(源码方式)
- SQL常用(通用)操作_01
- JS原型与原型链终极详解
- Linux 的cp命令
- laravel The requested URL /test was not found on this server.
- db2 9.7下删除一个schema下所有对象