艾伟:ASP.NET安全问题--Forms验证(后篇)--实战篇

简介: 验证流程讲述       我们首先假设一个场景:用户现在已经打开了我们的首页Default.aspx,但是有些资源只能是登录用户才可以看到的,那么如果这个用户想要查看这些资源,那么他就要登录。

       验证流程讲述

       我们首先假设一个场景:用户现在已经打开了我们的首页Default.aspx,但是有些资源只能是登录用户才可以看到的,那么如果这个用户想要查看这些资源,那么他就要登录。而且这个用户已经有了一个帐号。(我们本篇主要的话题是身份验证,至于创建用户账户是怎么创建的,我们不关心,方法很多,如直接一个数据库插入就行了!)
 
       我们现在就把我们的一些流程说下:
       1.用户登录,在输入框中输入用户名和密码信息
       2.点击登录按钮后,到数据库中查询该用户是否存在
       3 如果存在,服务器端代码就创建一个身份验证的票据,保存在cookie中,然后发送到客户端的浏览器
       4.用户已经有了验证的cookie,那么就页面就跳转到用户之前请求的页面

       数据库准备

       那么下面我们就开始详细讲述:
       首先,我们我们肯定要先得创建一个数据库,我们就取名为Login表,创建一个用户信息表,我们在在表中建立三个字段UserName,UserPassword,UserRole(大家可以创建更多字段,我这里只是演示,大家可以扩展的).  至于表中的数据,大家自己随便插入几条!
 
       代码编写
       因为我们常常要验证用户,所以我们把验证用户的代码写成一个方法放在App_Code目录下的Helpers.cs类中
       代码如下:

验证代码
public static bool ValidateUser(string username, string password)
{
      
    SqlConnection con 
= new SqlConnection();
    con.ConnectionString 
=
        ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString;

    SqlCommand com 
= new SqlCommand();
    com.Connection 
= con;
    com.CommandText 
= “Select Count(*) From Users Where Username=@Username and UserPassword=@Password”;

    com.Parameters.AddWithValue(“@Username”, username);
    com.Parameters.AddWithValue(“@Password”, password);
    con.Open();

    
int cnt = (int)com.ExecuteScalar();
    con.Close();

    
return (cnt > 0);
}

      然后我们就创建一个登录的页面Login.aspx,在页面上面放入两个TextBox,分别用来供用户输入用户名和密码。

      放上一个按钮,用来登录。

      回到Helpers.cs中,我再添加一个方法,来获取用户的角色:

Code
public static string  GetRoleForUser(string username )
{
        
//创建链接
    SqlConnection con = new SqlConnection();
    con.ConnectionString 
=
        ConfigurationManager.ConnectionStrings[“MyConnectionString”].ConnectionString;

    SqlCommand com 
= new SqlCommand();
    com.Connection 
= con;

        
//执行命令
    com.CommandText = “Select UseRole m Users Where Username=@Username;
    com.Parameters.AddWithValue(“@Username”, username);
         
    con.Open();

        
//返回结果
    string userRole= (string)com.ExecuteScalar();


    con.Close();
         
}

      为了启动Forms验证,我们还得到web.config文件中配置,如下:

< authentication  mode =”Forms”>
    
=”.mycookie”  path =”/”  loginUrl =”Login.aspx”  protection =”All”
timeout =”40”  />
authentication>

      并且不允许匿名用户访问我们的网站 :

< authorization >
  
< deny  users =”?”/>
>

      然后我们就开始在Login.aspx的登录按钮下面写代码了:

      基本思想如下:

      1.验证用户是否存在,

      2.如果存在,同时获取用户的角色

      3.创建身份验证票据和cookie,并且发送到客户端的浏览器中

     代码都加了注释,通过之前的基础,相信大家可以对下面的代码没有问题。

Code
Code
protected void LoginCallback(object sender, EventArgs e)
{
    
if (Helpers.ValidateUser(UserName.Text, Password.Text))
    {
                
//获取用户的角色
        string     rolenames = Helpers.GetRolesForUser(UserName.Text);
    
                
//创建身份验证票据
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                UserName.Text, DateTime.Now, DateTime.Now.AddSeconds(
40), false, roles);

                
//加密票据
        string encryptedTicket = FormsAuthentication.Encrypt(ticket);

                
//创建新的cookie
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
               
                
//把加密后的票据信息放入cookie
        cookie.Value = encryptedTicket;

                
//把cookie添加到响应流中
        Response.Cookies.Add(cookie);

                
//把cookie发送到客户端
        Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,false),true);

    }
}

      好了,现在如果我们正确的输入用户名和密码,那么我们的浏览器中就有了身份验证的cookie了,现在我们的页面就要马上从原来的Login.aspx转向到Default.aspx页面了,我们现在把这个转向的过程在头脑中把它慢速化,因为我们要分析这个过程。

       在Login.aspx转向到Default.aspx页面跳转的过程中,其实我们在请求Default.aspx页面,这个我们之前请求的过程没有任何的区别,也是一样要经历ASP.NET的一些生命周期,但是这次我们的浏览器中已经有了身份验证的cookie,ASP.NET运行时在处理,在处理Application_AuthenticateRequest事件时就要解析我们的cookie了。其实在之前我们登录之前,在这个事件代码中也解析了cookie的,只是那时候没有找到cookie而以。

       Application_AuthenticateRequest事件的代码中,其实就是解析cookie,然后把用户的身份标识,并且把用户的身份信息保存起来:

Code
Code
Code
void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpApplication app 
= (HttpApplication)sender;

        
//获取身份验证的cookie
    HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    
if (cookie != null)
    {
        
string encryptedTicket = cookie.Value;

                
//解密cookie中的票据信息
        FormsAuthenticationTicket ticket =
            FormsAuthentication.Decrypt(encryptedTicket);

                
//获取用户角色信息
        string[] roles = new string[]{ticket.UserData.toString()};

               
//创建用户标识
        FormsIdentity identity = new FormsIdentity(ticket);

                
//创建用户的主体信息
        System.Security.Principal.GenericPrincipal user =
        
new System.Security.Principal.GenericPrincipal(identity, roles);
        app.Context.User 
= user;
    }
}

      我们看到最后一行代码:app.Context.User = user;,把用户的身份以及角色信息保存在了User属性中。

      我们就可以在页面中通过如下方法判断用户是否登录了:

  if  (Page.User.Identity.IsAuthenticated)
  {
                        
//
  }

      用下面的方法判断用户是否属于某个角色:

if  (Page.User.IsInRole( " Admin " )
{
     
//
}

      其实这个我们之前讲过了的Identity,IPrincipal概念有关,不清楚的可以看看之前的文章!

      代码到这里,今天也写完了,有关身份验证的问题就要讲完了,还差一个问题没有讲述:自定义身份验证以及开发自定义的HttpModule.

      之后的的文章将讲述授权的问题。

目录
相关文章
|
3月前
|
开发框架 搜索推荐 算法
一个包含了 50+ C#/.NET编程技巧实战练习教程
一个包含了 50+ C#/.NET编程技巧实战练习教程
151 18
|
4月前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
65 5
|
4月前
|
消息中间件 开发框架 .NET
.NET 8 强大功能 IHostedService 与 BackgroundService 实战
【11月更文挑战第7天】本文介绍了 ASP.NET Core 中的 `IHostedService` 和 `BackgroundService` 接口及其用途。`IHostedService` 定义了 `StartAsync` 和 `StopAsync` 方法,用于在应用启动和停止时执行异步操作,适用于资源初始化和清理等任务。`BackgroundService` 是 `IHostedService` 的抽象实现,简化了后台任务的编写,通过 `ExecuteAsync` 方法实现长时间运行的任务逻辑。文章还提供了创建和注册这两个服务的实战步骤,帮助开发者在实际项目中应用这些功能。
164 0
|
5月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
102 1
|
6月前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
165 2
|
7月前
|
API 开发者 Java
API 版本控制不再难!Spring 框架带你玩转多样化的版本管理策略,轻松应对升级挑战!
【8月更文挑战第31天】在开发RESTful服务时,为解决向后兼容性问题,常需进行API版本控制。本文以Spring框架为例,探讨四种版本控制策略:URL版本控制、请求头版本控制、查询参数版本控制及媒体类型版本控制,并提供示例代码。此外,还介绍了通过自定义注解与过滤器实现更灵活的版本控制方案,帮助开发者根据项目需求选择最适合的方法,确保API演化的管理和客户端使用的稳定与兼容。
296 0
|
7月前
|
开发框架 缓存 前端开发
实战.NET Framework 迁移到 .NET 5/6
从.NET Framework 迁移到.NET 5/6 是一次重要的技术革新,涵盖开发环境与应用架构的全面升级。本文通过具体案例详细解析迁移流程,包括评估现有应用、利用.NET Portability Analyzer 工具识别可移植代码、创建新项目、逐步迁移代码及处理依赖项更新等关键步骤。特别关注命名空间调整、JSON 序列化工具更换及数据库访问层重构等内容,旨在帮助开发者掌握最佳实践,确保迁移过程平稳高效,同时提升应用性能与可维护性。
210 2
|
7月前
|
测试技术 API 开发者
.NET单元测试框架大比拼:MSTest、xUnit与NUnit的实战较量与选择指南
【8月更文挑战第28天】单元测试是软件开发中不可或缺的一环,它能够确保代码的质量和稳定性。在.NET生态系统中,MSTest、xUnit和NUnit是最为流行的单元测试框架。本文将对这三种测试框架进行全面解析,并通过示例代码展示它们的基本用法和特点。
599 8
|
7月前
|
开发框架 监控 安全
.NET 应用程序安全背后究竟隐藏着多少秘密?从编码到部署全揭秘!
【8月更文挑战第28天】在数字化时代,.NET 应用程序的安全至关重要。从编码阶段到部署,需全面防护以保障系统稳定与用户数据安全。开发者应遵循安全编码规范,实施输入验证、权限管理和加密敏感信息等措施,并利用安全测试发现潜在漏洞。此外,部署时还需选择安全的服务器环境,配置 HTTPS 并实时监控应用状态,确保全方位防护。
84 3
|
7月前
|
监控 Cloud Native 开发者
云端精英的.NET微服务秘籍:Azure上的创新实战演练
【8月更文挑战第28天】在现代软件开发中,微服务架构通过分解应用程序提升可维护性和扩展性。结合Azure与.NET框架,开发者能轻松打造高效且易管理的云原生微服务。首先,使用Docker容器化.NET应用,并借助Azure Kubernetes Service(AKS)或Azure Container Instances(ACI)部署。为确保高可用性和伸缩性,可利用Azure Traffic Manager负载均衡及Azure Autoscale动态调整实例数。
43 0

热门文章

最新文章