zoukankan      html  css  js  c++  java
  • 使用HttpContext的User属性来实现用户验证.NET教程

         httpcontext类包含了个别http请求的所有特定http信息。这个示例主要是讲如何使用httpcontext类中的user属性来实现用户验证!

    用户验证是大部分asp.net web应用程序都要用到的,它在整个应用程序中占有很重要的地位,在.net中,包含了很多种用户验证方式,如众所周知的passport认证,windows认证,form认证等等,可是这些都很难满足我们在实际应用中的需求,以致于很多朋友都是自己另外写代码来实现自己需要的功能,这让我们在安全性以及系统效率上要考虑很多。

    实际上,asp.net中内置的用户验证机制功能非常强大,同时也具有非常好的的可扩展性,它能够在httpcontext对象中生成一个名为user的属性,这个属性能让我们访问各种信息,包括用户是否已验证,用户的类型,用户名等等,我们还可以对该属性的功能进性扩展,以实现我们的要求。

    分配给httpcontext.user的对象必须实现iprincipal接口,而iprincipal定义的属性之一是identity,它必须实现iidentity接口。因为,我们只要写了实现这两个接口的类,就可以在这些类中添加任何我们所需要的功能。

    首先,我们创建两个实现iprincipal和iidentity的类,分另为myiprincipal和myidentity



    myiprincipal.cs



    using system;

    using system.collections;



    namespace httpcontextusereg

    {

    /// <summary>

    /// myprincipal 的摘要说明。

    /// </summary>

    /// 实现iprincipal接口

    public class myprincipal : system.security.principal.iprincipal

    {

    private system.security.principal.iidentity identity;

    private arraylist rolelist;



    public myprincipal(string userid,string password)

    {

    //

    // todo: 在此处添加构造函数逻辑

    //

    identity = new myidentity(userid,password);

    if(identity.isauthenticated)

    {

    //如果通过验证则获取该用户的role,这里可以修改为从数据库中

    //读取指定用户的role并将其添加到role中,本例中直接为用户添加一个admin角色

    rolelist = new arraylist();

    rolelist.add("admin");

    }

    else

    {

    // do nothing

    }

    }



    public arraylist rolelist

    {

    get

    {

    return rolelist;

    }

    }

    #region iprincipal 成员



    public system.security.principal.iidentity identity

    {

    get

    {

    // todo: 添加 myprincipal.identity getter 实现

    return identity;

    }

    set

    {

    identity = value;

    }

    }



    public bool isinrole(string role)

    {

    // todo: 添加 myprincipal.isinrole 实现

    return rolelist.contains(role);;

    }



    #endregion

    }

    }





    myidentity.cs



    using system;



    namespace httpcontextusereg

    {

    /// <summary>

    /// myidentity 的摘要说明。

    /// </summary>

    /// 实现iidentity接口

    public class myidentity : system.security.principal.iidentity

    {

    private string userid;

    private string password;



    public myidentity(string currentuserid,string currentpassword)

    {

    //

    // todo: 在此处添加构造函数逻辑

    //

    userid = currentuserid;

    password = currentpassword;

    }



    private bool canpass()

    {

    //这里朋友们可以根据自己的需要改为从数据库中验证用户名和密码,

    //这里为了方便我直接指定的字符串

    if(userid == "yan0lovesha" && password == "iloveshasha")

    {

    return true;

    }

    else

    {

    return false;

    }

    }



    public string password

    {

    get

    {

    return password;

    }

    set

    {

    password = value;

    }

    }



    #region iidentity 成员



    public bool isauthenticated

    {

    get

    {

    // todo: 添加 myidentity.isauthenticated getter 实现

    return canpass();

    }

    }



    public string name

    {

    get

    {

    // todo: 添加 myidentity.name getter 实现

    return userid;

    }

    }



    //这个属性我们可以根据自己的需要来灵活使用,在本例中没有用到它

    public string authenticationtype

    {

    get

    {

    // todo: 添加 myidentity.authenticationtype getter 实现

    return null;

    }

    }



    #endregion

    }

    }



    在完成了这两个类之后我们还要创建一个自己的page类,来配合我们的验证,这里我们将其命名为mypage,继承自page类



    mypage.cs



    using system;

    using system.collections;



    namespace httpcontextusereg

    {

    /// <summary>

    /// mypage 的摘要说明。

    /// </summary>

    /// 继承自page类

    public class mypage : system.web.ui.page

    {

    public mypage()

    {

    //

    // todo: 在此处添加构造函数逻辑

    //

    }



    protected override void oninit(eventargs e)

    {

    base.oninit (e);

    this.load +=new eventhandler(mypage_load);

    }



    //在页面加载的时候从缓存中提取用户信息

    private void mypage_load(object sender, system.eventargs e)

    {

    if(context.user.identity.isauthenticated)

    {

    if(context.cache["usermessage"] != null)

    {

    hashtable usermessage = (hashtable)context.cache["usermessage"];

    myprincipal principal = new myprincipal(usermessage["userid"].tostring(),usermessage["userpassword"].tostring());

    context.user = principal;

    }

    }

    }

    }

    }



    下面就是我们的界面webform.aspx和webform.aspx.cs



    webform.aspx



    <%@ page language="c#" codebehind="webform1.aspx.cs" autoeventwireup="false" inherits="httpcontextusereg.webform1" %>

    <!doctype html public "-//w3c//dtd html 4.0 transitional//en" >

    <html>

    <head>

    <title>webform1</title>

    <meta content="microsoft visual studio .net 7.1" name="generator">

    <meta content="c#" name="code_language">

    <meta content="javascript" name="vs_defaultclientscript">

    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetschema">

    </head>

    <body>

    <form id="form1" method="post" runat="server">

    <p><font face="宋体">用户名:

    <asp:textbox id="tbxuserid" runat="server"></asp:textbox><br>

    密 码:

    <asp:textbox id="tbxpassword" runat="server" textmode="password"></asp:textbox></font></p>

    <p><font face="宋体">

    <asp:button id="btnlogin" runat="server" text="登录"></asp:button>

    <asp:label id="lblloginmessage" runat="server"></asp:label></font></p>

    <p><font face="宋体">

    <asp:panel id="panel1" runat="server" visible="false">

    <p>

    <asp:button id="btnadmin" runat="server" text="角色1"></asp:button>

    <asp:button id="btnuser" runat="server" text="角色2"></asp:button></p>

    <p>

    <asp:label id="lblrolemessage" runat="server"></asp:label></p>

    </asp:panel>

    <p></p>

    </font>

    </form>

    </body>

    </html>



    webform1.aspx.cs



    using system;

    using system.collections;

    using system.componentmodel;

    using system.data;

    using system.drawing;

    using system.web;

    using system.web.caching;

    using system.web.sessionstate;

    using system.web.ui;

    using system.web.ui.webcontrols;

    using system.web.ui.htmlcontrols;



    namespace httpcontextusereg

    {

    /// <summary>

    /// webform1 的摘要说明。

    /// </summary>

    /// 将这里本来继承自page类改为继承自我们自己的mypage类

    public class webform1 : httpcontextusereg.mypage

    {

    protected system.web.ui.webcontrols.textbox tbxuserid;

    protected system.web.ui.webcontrols.textbox tbxpassword;

    protected system.web.ui.webcontrols.panel panel1;

    protected system.web.ui.webcontrols.button btnadmin;

    protected system.web.ui.webcontrols.button btnuser;

    protected system.web.ui.webcontrols.label lblrolemessage;

    protected system.web.ui.webcontrols.label lblloginmessage;

    protected system.web.ui.webcontrols.button btnlogin;



    private void page_load(object sender, system.eventargs e)

    {

    // 在此处放置用户代码以初始化页面

    }



    #region web 窗体设计器生成的代码

    override protected void oninit(eventargs e)

    {

    //

    // codegen: 该调用是 asp.net web 窗体设计器所必需的。

    //

    initializecomponent();

    base.oninit(e);

    }



    /// <summary>

    /// 设计器支持所需的方法 - 不要使用代码编辑器修改

    /// 此方法的内容。

    /// </summary>

    private void initializecomponent()

    {

    this.btnlogin.click += new system.eventhandler(this.btnlogin_click);

    this.btnadmin.click += new system.eventhandler(this.btnadmin_click);

    this.btnuser.click += new system.eventhandler(this.btnuser_click);

    this.load += new system.eventhandler(this.page_load);



    }

    #endregion



    private void btnlogin_click(object sender, system.eventargs e)

    {

    myprincipal principal = new myprincipal(tbxuserid.text,tbxpassword.text);

    if(!principal.identity.isauthenticated)

    {

    lblloginmessage.text = "用户名或密码不正确";

    panel1.visible = false;

    }

    else

    {

    // 如果用户通过验证,则将用户信息保存在缓存中,以备后用

    // 在实际中,朋友们可以尝试使用用户验证票的方式来保存用户信息,这也是.net内置的用户处理机制

    context.user = principal;

    hashtable usermessage = new hashtable();

    usermessage.add("userid",tbxuserid.text);

    usermessage.add("userpassword",tbxpassword.text);

    context.cache.insert("usermessage",usermessage);

    lblloginmessage.text = tbxuserid.text + "已经登录";

    panel1.visible = true;

    }

    }



    private void btnadmin_click(object sender, system.eventargs e)

    {

    // 验证用户的role中是否包含admin

    if(context.user.isinrole("admin"))

    {

    lblrolemessage.text = "用户" + ((myprincipal)context.user).identity.name + "属于admin组";

    }

    else

    {

    lblrolemessage.text = "用户" + context.user.identity.name + "不属于admin组";

    }

    }



    private void btnuser_click(object sender, system.eventargs e)

    {

    // 验证用户的role中是否包含user

    if(context.user.isinrole("user"))

    {

    lblrolemessage.text = "用户" + context.user.identity.name + "属于user组";

    }

    else

    {

    lblrolemessage.text = "用户" + context.user.identity.name + "不属于user组";

    }

    }

    }

    }

    代码部分介绍完了,朋友们可以自己试试来看到效果,在这个例子中很多地方都为了方便而直接给予赋值,在实际应用中,这些将是从数据库或从其它配置文件中得到,而这种方法的可扩展性是非常高的,我们可以根据自己的需要来扩展myiprincipal和myidentity类的功能。比如我们可以添加一个isinpermission来使用户不仅属于角色,每个角色还可以拥有不同的权限。在本例中,在用户验证过后是通过使用缓存来保存已验证用户的信息的,我们还可以尝试使用用户验证票的方式来实现。

    我们可以看到,这种用户验证机制,在我们的程序越宠大,它所带来的好处就越多,而且他还有很多值得我们发掘的地方!

    希望大家能和我互相交流!谢谢!

  • 相关阅读:
    Core Animation 文档翻译—附录C(KVC扩展)
    Core Animation 文档翻译—附录B(可动画的属性)
    Core Animation 文档翻译—附录A(Layer样貌相关属性动画)
    Core Animation 文档翻译 (第八篇)—提高动画的性能
    Core Animation 文档翻译 (第七篇)—改变Layer的默认动画
    Core Animation 文档翻译 (第六篇)—高级动画技巧
    Core Animation 文档翻译 (第五篇)—构建Layer的层次结构
    用Markdown快速排版一片文章
    Core Animation 文档翻译 (第四篇)—让Layer的content动画起来
    Core Animation 文档翻译(第三篇)—设置Layer对象
  • 原文地址:https://www.cnblogs.com/chorrysky/p/2760085.html
Copyright © 2011-2022 走看看