您的位置:首页 > 其它

Nancy之Forms authentication的简单使用

2016-02-17 15:41 323 查看

一、前言

想必大家或多或少都听过微软推出的ASP.NET Identity技术,可以简单的认为就是一种授权的实现

很巧的是,Nancy中也有与之相类似的技术Authentication,这两者之间都用到了一些相通的安全技术

(我没有去看ASP.NET Identity的内部实现,是从它的简单用法中判断的)

正式开始介绍之前先推荐几篇ASP.NET Identity的好文章

r01cnASP.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: