本文转自:http://www.cnblogs.com/amylis_chen/archive/2012/08/02/2620129.html

Default.aspx 页面预览

默认情况下SignIn.aspx在登录成功后会导航到Default.aspx页面,所以我们先简单的构建一下Default.aspx页面,看看实现的效果:

<asp:LoginView ID="LoginView1" runat="server">
<AnonymousTemplate>
欢迎访问, 游客 !
</AnonymousTemplate>
<LoggedInTemplate>
你好, <asp:LoginName ID="LoginName1" runat="server" /> ! <br />
<strong>UserData值:</strong>
<asp:Literal ID="lbUserData" runat="server" />
</LoggedInTemplate>
</asp:LoginView>
<br />
<asp:LoginStatus ID="LoginStatus1" runat="server" LogoutPageUrl="~/Logout.aspx" LogoutAction="Redirect" /> 类似地,我们放置了一个LoginView控件,只是这里我们多放置了一个LoginStatus控件。接下来我们看一下后置代码: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) {
if (Request.IsAuthenticated) {
FormsIdentity identity = User.Identity as FormsIdentity;
string userData = identity.Ticket.UserData;
Literal lbUserData = LoginView1.FindControl("lbUserData") as Literal;
lbUserData.Text = userData;
}
}
} 最后我们先进行登录,然后再打开Default.aspx页面,会看到类似这样的输出: 至此,我们已经看到了如何利用FormsAuthentionTicket来附带额外的用户数据,但是我们应该看到这种做法存在的问题:可以保存的数据过于单一,仅仅只是一个字符串。而我们第一节中所介绍的用户表包括各种类型的各种数据。如果你看过了 从一个范例看XML的应用 这篇文章,你应该立刻想到此处又是一个“单一字符串保存多种不同类型数据”的应用场景,我们可以定义XML来解决。对于这种方式,我不再演示了。实际上,我们可以自定义一个IPrincipal和IIdentity来完成,接下来就来看一下。 自定义IPrincipal和IIdentity 不管是在Windows上还是在Web上,.Net都使用这两个接口来实现用户的身份验证。它们不过是一个接口,实现了这两个接口的类型附带了用户的信息,最终被赋予线程(Windows)或Cookie(Web)来对用户进行验证。我们在App_Code下添加CustomPrincipal和CustomIdentity来实现这两个接口: public class CustomPrincipal : IPrincipal { private CustomIdentity identity; public CustomPrincipal(CustomIdentity identity) {
this.identity = identity;
} public IIdentity Identity {
get {
return identity;
}
} public bool IsInRole(string role) {
return false;
}
} public class CustomIdentity : IIdentity {
private FormsAuthenticationTicket ticket;
private HttpContext context = HttpContext.Current; public CustomIdentity(FormsAuthenticationTicket ticket) {
this.ticket = ticket;
} public string AuthenticationType {
get { return "Custom"; }
} public bool IsAuthenticated {
get { return true; }
} public string Name {
get {
return ticket.Name;
}
} public FormsAuthenticationTicket Ticket {
get { return ticket; }
} // 这里可以是任意来自数据库的值,由Name属性取得
// 需要注意此时已通过身份验证
public string Email {
get {
HttpCookie cookie = context.Request.Cookies["Email"]; if (cookie==null || String.IsNullOrEmpty(cookie.Value)) {
string type = "jimmy_dev[at]163.com"; // 实际应根据name属性从数据库中获得
cookie = new HttpCookie("UserType", type);
cookie.Expires = DateTime.Now.AddDays();
context.Response.Cookies.Add(cookie);
} return cookie.Value;
}
} public string HomePage {
get {
HttpCookie cookie = context.Request.Cookies["HomePage"]; if (cookie==null || String.IsNullOrEmpty(cookie.Value)) {
string name = "www.tracefact.net"; // 实际应根据name属性从数据库中获得
cookie = new HttpCookie("NickName", name);
cookie.Expires = DateTime.Now.AddDays();
context.Response.Cookies.Add(cookie);
}
return cookie.Value;
}
}
} 注意这里的HomePage和Email这两个属性,它们携带了我们的用户数据,这里我仅仅是对它们进行了一个简单的赋值,实际的数值应该是来自于数据库。还要注意获取到它们的值后被保存在了Cookie中,以避免频繁的对数据库进行访问。 定义了实现这两个接口的对象之后,我们还需要把它嵌入到应用程序的生命周期中,具体的做法就是挂接到HttpModule或者是重写Global.asax中的事件,这里我采用了重写Global.asax事件的方式,因此创建一个Global.asax文件,然后添加如下代码: void Application_OnPostAuthenticateRequest(object sender, EventArgs e) {
IPrincipal user = HttpContext.Current.User; if (user.Identity.IsAuthenticated
&& user.Identity.AuthenticationType == "Forms") { FormsIdentity formIdentity = user.Identity as FormsIdentity;
CustomIdentity identity = new CustomIdentity(formIdentity.Ticket); CustomPrincipal principal = new CustomPrincipal(identity);
HttpContext.Current.User = principal; Thread.CurrentPrincipal = principal;
}
} 这段代码很好理解,它不过是在应用程序的PostAuthenticateRequest事件中用我们自定义的CustomPrincipal和CustomIdentity替换掉了默认的IPrincipal和IIdentity实现。 Default.aspx页面预览 我们再次对Default.aspx进行修改,添加两个Literal控件,用于显示我们自定义的数值: 自定义Identity中的值:<br />
<strong>Email:</strong>
<asp:Literal ID="ltrEmail2" runat="server"></asp:Literal><br /> <strong>HomePage:</strong>
<asp:Literal ID="ltrHomePage" runat="server"></asp:Literal><br /> 然后修改页面的代码,使用我们的自定义CustomIdentity,然后从中获得自定义的属性值: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) {
if (Request.IsAuthenticated) { CustomIdentity identity = User.Identity as CustomIdentity;
if (identity != null) {
// 获得UserData中的值
string userData = identity.Ticket.UserData;
Literal lbUserData = LoginView1.FindControl("lbUserData") as Literal;
lbUserData.Text = userData; // 获得identity中的值
ltrEmail2.Text = identity.Email;
ltrHomePage.Text = identity.HomePage;
}
}
}
} 如果你现在打开页面,将会看到类似下面的页面: 可以看到我们获得了定义在CustomIdentity中的属性。注意这里我只是做了一个示范,因此只在CustomIdentity中包含了Email和HomePage两个属性值,如果看到此处你便以为大功告成,然后将所有未完成的属性都添加到CustomIdentity中去就大错特错了。Identity的目的只是为你提供一个已经登录了的用户的名称,而不是携带所有的用户信息,这些信息应该由其他的类型提供。因此微软才定义了MemberShipUser类型和Profile。从这个角度上来看,自定义IPrincipal和IIdentity并没有太大的意义。 这里,我们最好是定义一个自己的类型来承载用户数据,下面我们就看下如何完成。 自定义类型携带用户数据 在App_Code中新建一个SiteUser类,它的实现如下,简单起见,我使用了公有字段而非属性: public class SiteUser
{
public string Name;
public string UserImage;
public DateTime RegisterDate;
public string Email;
public string HomePage;
public int PostCount;
public int ReplyCount;
public byte Level; public SiteUser(AuthDataSet.UserRow userRow) {
this.Email = userRow.Email;
this.HomePage = userRow.Homepage;
this.Level = userRow.Level;
this.Name = userRow.Name;
this.PostCount = userRow.PostCount;
this.RegisterDate = userRow.RegisterDate;
this.ReplyCount = userRow.ReplyCount;
this.UserImage = userRow.UserImage;
} // 实际应该由数据库获得
public static SiteUser GetUser(string name) { AuthDataSetTableAdapters.UserTableAdapter adapter
= new AuthDataSetTableAdapters.UserTableAdapter();
AuthDataSet.UserDataTable userTable = adapter.GetUserTable(name); if(userTable.Rows.Count >){
return new SiteUser((AuthDataSet.UserRow)userTable.Rows[]);
} // 因为调用这个方法时,name应该是有效的,
// 如果name无效,直接抛出异常
throw new ApplicationException("User Not Found");
}
} 它的GetUser()静态方法根据用户的名称获得了一个SiteUser对象,这里需要注意的是通常调用这个方法时,用户已经登录过了,也就是说其name参数总是有效的,因此当搜索数据库找不到记录时,我简单地抛出了异常。

[转]Asp.Net 用户验证(自定义IPrincipal和IIdentity)的更多相关文章

  1. Asp.Net 用户验证(自定义IPrincipal和IIdentity)

    http://www.cnblogs.com/JimmyZhang/archive/2008/12/07/1349457.html

  2. ASP.NET MVC验证 - 自定义验证规则、验证2个属性值不等【待验证】

    提示:保存后才提示错误信息 自定义验证特性,继承ValidationAttribute并实现IClientValidatable 这次重写了基类的IsValid()方法的另外一个重载,因为该重载包含了 ...

  3. Asp.net MVC验证那些事(4)-- 自定义验证特性

    在项目的实际使用中,MVC默认提供的Validation Attribute往往不够用,难以应付现实中复杂多变的验证需求.比如, 在注册用户的过程中,往往需要用户勾选”免责声明”,这个checkbox ...

  4. asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功。请重试。 Login控件

    原文:asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功.请重试. Login控件 现象1.asp.net使用自定义sql server身份验证数据库,在A机器新增用户A,可以登录成 ...

  5. 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2)

    前言: 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(65)-MVC WebApi 用户验证 (1) 回顾上一节,我们利用webapi简单的登录并 ...

  6. ASP.NET MVC 5 WEB API 用户验证

    参考博客:ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1) 参考博客:MVC WebApi 用户验证 (2)构建ASP.NET MVC5+E ...

  7. [Asp.Net MVC4]验证用户登录实现

    最近我们要做一个仿sina的微博,碰巧的是我最近在学习mvc,就想用mvc技术实现这个项目. 既然是微博,那不用想也应该知道肯定要有用户登陆,但是和常规的asp.net登陆又不一样,以下是我一下午+一 ...

  8. CAS 单点登录【2】自定义用户验证

       基础不太熟的同学可以先去看:CAS 单点登录[1]入门 方案1:CAS默认的JDBC扩展方案: CAS自带了两种简单的通过JDBC方式验证用户的处理器. 1.QueryDatabaseAuthe ...

  9. ASP.NET与ASP.NET Core用户验证Cookie并存解决方案

    在你将现有的用户登录(Sign In)站点从ASP.NET迁移至ASP.NET Core时,你将面临这样一个问题——如何让ASP.NET与ASP.NET Core用户验证Cookie并存,让ASP.N ...

随机推荐

  1. ECS Linux 服务器解除ssh登陆后被锁定或暂停输入输出的终端

    在使用SSH终端(如Xshell)登陆时,若不慎点击 Ctrl + S  按键,会导致终端很像被锁定,输入和输出都无响应. 这是由于操作系统的终端收到指令 Ctrl + S 后,会暂停终端输入输出的刷 ...

  2. <a> href属性--记录八

    1.去掉<a>标签的下划线 <ul style=" list-style-type:none; margin:0;color:Gray; font-size:11px;ma ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构

    系列目录 前言:  这应该是本系统最后一次重构,将重构BLL层和Model层.来完全取代代码生成器生成的BLL层和DAL层.完全废掉了代码生成器的DAL,BLL,MODEL层.  全自动生成增,删,改 ...

  4. 从零开始编写自己的C#框架(12)——T4模板在逻辑层中的应用(一)(附源码)

    对于T4模板很多朋友都不太熟悉,它在项目开发中,会帮我们减轻很大的工作量,提升我们的开发效率,减少出错概率.所以学好T4模板的应用,对于开发人员来说是非常重要的. 园子里对于T4模板的介绍与资料已经太 ...

  5. JavaScript中尺寸、坐标

    测试环境是IE8,Chrome38,Firefox40,下面是全局通用脚本打印代码 /** * 打印 */ function write(str) { document.write(str + '&l ...

  6. jvm系列(六):jvm调优-从eclipse开始

    jvm调优-从eclipse开始 概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程 ...

  7. java笔记--笔试中极容易出错的表达式的陷阱

    我相信每一个学过java的人儿们都被java表达式虐过,各种"肯定是它,我不可能错!",然后各种"尼玛,真假,怎么可能?",虽然在实际开发中很少会真的让你去使用 ...

  8. ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  9. TeamCity : 自动触发 Build

    创建了 build 的配置以后,您既可以手动点击 "Run" 按钮来触发一次 build 过程,也可以通过 Triggers 配置实现自动触发 build 过程.一个 trigge ...

  10. [Asp.net 5] Caching-缓存架构与源码分析

    首先奉献caching的开源地址[微软源码] 1.工程架构 为了提高程序效率,我们经常将一些不频繁修改,但是使用了还很大的数据进行缓存.尤其是互联网产品,缓存可以说是提升效率优化第一利器.微软为我们实 ...