在开发过程中,我们需要做的事情包括:

1. 在 web.config 中设置 Forms 身份验证相关参数。
2. 创建登录页。

登录页中的操作包括:

1. 验证用户名和密码是否正确。
2. 创建身份验证票证对象。
3. 将身份验证票证对象加密成字符串,写入 Cookies。
4. 重定向到原始请求 URL。

1. 简单演示

web.config
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
    <authentication mode="Forms">
      <forms loginUrl="~/logon.aspx" name="MyAuthForm">
        <credentials passwordFormat="Clear">
          <user name="username" password="password"/>
        </credentials>
      </forms>
    </authentication>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</configuration>


logon.aspx
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  protected void Button1_Click(object sender, EventArgs e)
  {
    if (FormsAuthentication.Authenticate(this.txtUsername.Text, this.txtPassword.Text))
      FormsAuthentication.RedirectFromLoginPage(this.txtUsername.Text, true);
    else
      Response.Write("用户名或密码错误!");
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
 <title>登录页</title>
</head>
<body>
 <form id="form1" runat="server">
 <div>
    Username: <asp:TextBox ID="txtUsername" runat="server" Width="100px" Text="username"></asp:TextBox><br />
    Password: <asp:TextBox ID="txtPassword" runat="server" Width="100px" Text="password"></asp:TextBox><br />
    <asp:Button ID="Button1" runat="server" Text="Sign In" OnClick="Button1_Click" />
 </div>
 </form>
</body>
</html>

2. Forms 验证参数

如果只是某些子目录中的页面访问请求需要进行身份验证,那么可以修改一下根路径下的 web.config。

web.config
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
    <authentication mode="Forms">
      <forms loginUrl="~/logon.aspx" name="MyAuthForm">
        <credentials passwordFormat="Clear">
          <user name="username" password="password"/>
        </credentials>
      </forms>
    </authentication>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</configuration>

然后在需要进行身份验证的子目录中创建一个新的 web.config。

<?xml version="1.0"?>
<configuration>
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</configuration>

我们还可以在根路径下的 web.config 中指定相关参数来控制身份验证模式。

cookieless 
  定义是否使用 Cookie 以及 Cookie 的行为。
  .UseCookies 
    指定无论在什么设备上都始终使用 Cookie。
  .UseUri 
    指定从不使用 Cookie。
  .AutoDetect 
    如果设备配置文件支持 Cookie,则指定使用 Cookie;否则不使用 Cookie。
  .UseDeviceProfile 
    如果浏览器支持 Cookie,则指定使用 Cookie;否则不使用 Cookie。 
    对于支持 Cookie 的设备,不尝试通过探测来确定是否已启用 Cookie 支持。
 
defaultUrl 
  定义在身份验证之后用于重定向的默认 URL。 默认值为 "default.aspx"。
  当我们直接打开登录页进行登录后,该属性就很重要了。

loginUrl 
  指定如果找不到任何有效的身份验证 Cookie,将请求重定向到的用于登录的 URL。默认值为 login.aspx。
 
name 
  指定要用于身份验证的 HTTP Cookie。如果正在一台服务器上运行多个应用程序并且每个应用程序都需要
  唯一的 Cookie,则必须在每个应用程序的 Web.config 文件中配置 Cookie 名称。默认值为 ".ASPXAUTH"。
 
path 
  为应用程序发出的 Cookie 指定路径。 
  默认值是斜杠 (/),这是因为大多数浏览器是区分大小写的,如果路径大小写不匹配,浏览器不会送回 Cookie。
 
timeout 
  指定 Cookie 过期前逝去的时间(以整数分钟为单位)。持久性 Cookie 不超时。默认值为 "30"(30 分钟)。

更详细信息,请参考 MSDN 文档。
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/dv_ASPNETgenref/html/8163b8b5-ea6c-46c8-b5a9-c4c3de31c0b3.htm

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
    <authentication mode="Forms">
      <forms loginUrl="~/logon.aspx" name="MyForm" defaultUrl="index.aspx" timeout="10">
        <credentials passwordFormat="Clear">
          <user name="username" password="password"/>
        </credentials>
      </forms>
    </authentication>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</configuration>

3. 验证方法

我们可以使用下面 4 种方法中的一种进行票证写入和重定向操作,其实前 3 种只不过是对第 4 种方法的封装而已。推荐使用 1、4。注意后三种方法不支持cookieless="UseUri"。

// 1. 使用缺省身份验证票证
FormsAuthentication.RedirectFromLoginPage("username", true);

// 2. 使用缺省身份验证票证
FormsAuthentication.SetAuthCookie("username", false);
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));

// 3. 使用缺省身份验证票证
Response.Cookies.Add(FormsAuthentication.GetAuthCookie("username", false));
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));

// 4. 使用自定义身份验证票证
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "username", DateTime.Now, DateTime.Now.AddMinutes(10), false, null);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)));
Response.Redirect(FormsAuthentication.GetRedirectUrl("username", false));

4. 自定义身份标识类型

MSDN 文档告诉我们,可以在 Global.asax 中通过 Authenticate 事件使用自定义 Principal、Identity 替代 GenericPrincipal、FormsIdentity。因为 Authenticate 事件在 AuthenticateRequest 事件期间引发,因此我们可以在其他模块之前创建用户身份标识对象(FormsAuthenticationEventArgs.User)。

ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref12/html/T_System_Web_Security_FormsAuthenticationEventHandler.htm

class MyPrincipal : System.Security.Principal.IPrincipal
{
  // 
}

class MyIdentity : System.Security.Principal.IIdentity
{
  // 
}
  
public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
  if (FormsAuthentication.CookiesSupported)
  {
    if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
    {
      try
      {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
          Request.Cookies[FormsAuthentication.FormsCookieName].Value);
 
        args.User = new MyPrincipal(new MyIdentity (ticket), new string[0]);
      }
      catch (Exception e)
      {
        // Decrypt method failed.
      }
    }
  }
  else
  {
    throw new HttpException("Cookieless Forms Authentication is not " +
      "supported for this application.");
  }

}

当然,还有另外一种简便的方法。

if (!(HttpContext.Current.User is MyPrincipal))
{
  HttpContext.Current.User = new MyPrincipal(new MyIdentity(ticket), roles);
}

只不过,你要找一个合适的时机而已。

5. FormsAuthentication

Authenticate 
对照存储在应用程序配置文件中的凭据来验证用户名和密码。该方法只能验证存储在 web.config 中的用户名和密码信息,大多数时候我们会用自己的验证方法替代它。

Decrypt 
解密从 Cookie 中获取的加密字符串,创建 FormsAuthenticationTicket 对象。 

Encrypt 
加密 FormsAuthenticationTicket,返回加密后字符串。

GetRedirectUrl 
返回导致重定向到登录页的原始请求 URL。GetRedirectUrl 方法返回查询字符串中使用 ReturnURL 变量名指定的 URL。例如,在 URL http://www.contoso.com/login.aspx?ReturnUrl=caller.aspx 中,GetRedirectUrl 方法返回返回 caller.aspx。如果 ReturnURL 变量不存在,GetRedirectUrl 方法将返回 DefaultUrl 属性中的 URL。

RedirectFromLoginPage 
将经过身份验证的用户重定向回最初请求的 URL 或 DefaultUrl 。 

RedirectToLoginPage 
将浏览器重定向到登录 URL。 

RenewTicketIfOld 
有条件地更新 FormsAuthenticationTicket 的发出日期和时间以及过期日期和时间。 注意该方法只是返回更新后的 FormsAuthenticationTicket 对象,并不会写入 Cookies。

GetAuthCookie 
为给定的用户名创建身份验证 Cookie,并不添加到响应的 Cookie 集合或 URL。 

SetAuthCookie 
为提供的用户名创建一个身份验证票证,并将其添加到响应的 Cookie 集合或 URL。 

SignOut 
从浏览器删除 Forms 身份验证票证。 

6. 票证自定义数据应用

使用自定义票证时,我们可以添加一个 userData 参数。善加利用这个参数还是能带了一些意想不到的好处的,诸如存储用户 VIP 等级编号,所拥有的权限/角色集合等。当然 Cookie 和 URL 参数长度有限,这个自定义数据不能太长。 

[转][.NET 基于角色安全性验证] 之三:ASP.NET Forms 身份验证相关推荐

  1. 实现基于 ASP.NET Forms 身份验证的跨子域单点登录

    对于跨应用程序的 ASP.NET Forms 身份验证,相信大家应该都不陌生,几年前很多文章都介绍了如何实现,比如 MSDN 的 跨应用程序进行 Forms 身份验证,唐朝程序员 的 ASP.NET站 ...

  2. asp.net Forms身份验证

    Web.config中的配置 <system.web> <authentication mode="Forms"> <forms name=" ...

  3. ASP.net的身份验证方式有哪些?分别是什么原理?

    Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活. Forms 验证方式对基于用户的验证授 ...

  4. ASP.NET Forms权限验证

    安全性是 ASP.NET Web 应用程序中一个非常重要的方面.它涉及内容非常广泛,不能在一篇文章内说明所有的安全规范,本文讲述如何利用Forms 身份验证构建安全的 ASP.NET 应用程序,它是目 ...

  5. Forms身份验证基本原理

    要采用Forms身份验证,先要在应用程序根目录中的Web.config中做相应的设置: <authentication mode="forms">     <fo ...

  6. .NET Forms身份验证

    .NET表单身份验证 ASP.NET Forms 身份验证的简单实现:1)在Web.config文件中配置应用程序使用 Forms 身份验证:2)创建登陆页面,将用户身份验证票证添加到Cookie集合 ...

  7. [转][.NET 基于角色安全性验证] 之一:基础知识

    .NET 基于角色安全性验证的核心是主体(Principal)和标识(Identity)对象,其中主体负责角色或者组的验证,标识对象封装有关正在验证的用户或实体的信息.角色安全性验证通过生成可供当前线 ...

  8. java验证身份证合法性_Java安全性,第2部分:身份验证和授权

    关于本教程 本教程是关于什么的? 也许没有比应用程序安全更重要的软件工程主题. 攻击是昂贵的,无论是来自内部还是外部,而且某些攻击可能会使软件公司承担赔偿责任. 随着计算机(尤其是Internet)技 ...

  9. Asp.Net MVC 身份验证-Forms

    Asp.Net MVC 身份验证-Forms 在MVC中对于需要登录才可以访问的页面,只需要在对应的Controller或Action上添加特性[Authorize]就可以限制非登录用户访问该页面.那 ...

最新文章

  1. requestanimationframe_requestAnimationFrame详解以及无线页面优化
  2. Codeforces Round #359 div2
  3. stream流把list转为map
  4. 自动化集成:Pipeline整合Docker+K8S
  5. 无源波分和彩光模块_5G前传WDM解决方案,无源波分和彩光模块
  6. mysql中添加中文存储和显示功能
  7. linux设置为lunux文件夹,Linux设置环境变量时如何修改文件
  8. 黑色星期五 问题描述   有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是“诸事不宜”。请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又
  9. 人机交互之Web界面设计与CNN大作业
  10. 一篇讲透图表操作:趋势类比较类占比类分布类图表
  11. 计算24点游戏C语言课设
  12. 白领巧学燕子飞可治颈椎疼
  13. 吃货联盟订餐系统(用数组写的)
  14. win10计算机安全模式怎么,Win10系统电脑进入安全模式的两种方法
  15. 回忆着你对我的承诺、一切的一切在那个夏季散了
  16. 什么是API,SDK和API之间有什么关系呢?
  17. VMware Workstation导出的ovf格式虚拟机 不能用VirtualBox导入
  18. 高并发和大流量解决方案
  19. schrodinger 薛定谔
  20. 昨晚(2009-09-08),自己的第一个项目上线成功,踩个脚印

热门文章

  1. 人工智能 | 增强小目标检测(Augmentation for small object detection)
  2. 命令行参数实现10万行小字典程序并输出查找时间
  3. 嵌入式系统开发入门二:C语言的几个注意事项
  4. 装linux时可用空间只有1929k,求Linux命令习题
  5. Java基础day6
  6. linux内核杂记(3)-进程(1)
  7. luogu p4767 邮局
  8. 温州大学计算机与人工智能学院2022年硕士研究生招生复试咨询开始啦!
  9. 【深度学习】越来越卷,教你使用Python实现卷积神经网络(CNN)
  10. 【Python基础】Python开发环境设置和小技巧