zoukankan      html  css  js  c++  java
  • ASP.NET自定义身份验证的实践

    事情是这样的:有一套ASP.NET应用程序,用户一般会用工号登录,但是我们希望在应用程序中方便地访问到该用户相关的其他信息,例如用户名或者工厂名称。

    按照标准的ASP.NET Membership的做法,它不能提供这样的信息。Page.User.Identity.Name只是返回用户登录时使用的名称,在本例中是工号。

    我们的目标是,能不能实现Page.User.Identity.Name显示用户的真实名称,而不是工号,甚至还可以显示其他的一些信息。

    要实现这样的功能,我的思路是自定义身份验证。下面就是我的步骤,可以供大家参考

    第一步:自定义Identity

    Identity在安全设计中很重要,他一般代表了用户标识。本例中,我们添加了几个特殊的属性

        public class SECIdentity : IIdentity
        {
    
    
            public string DisplayName { get; set; }
            public string Factory { get; set; }
            public string Name { get; set; }
    
    
    
    
            public string AuthenticationType
            {
                get { return "Custom Authentication"; }
            }
    
            public bool IsAuthenticated
            {
                get { return true; }
            }
            public override string ToString()
            {
                return string.Format("{0},{1}", Factory, DisplayName);
            }
        }

    第二步:自定义Principal

    一个用户不仅需要有名称等基本信息,它还应该具有另外一些信息,例如角色等等。这可以通过封装成一个Principal来解决

        public class SECPrincipal : IPrincipal
        {
            public SECPrincipal(string name, string displayName, string factory)
            {
                identity = new SECIdentity()
                {
                    Name = name,
                    DisplayName = displayName,
                    Factory = factory
                };
            }
            private IIdentity identity;
            public IIdentity Identity
            {
                get
                {
                    return identity;
                }
            }
    
            public bool IsInRole(string role)
            {
                return true;
            }
        }

    第三步:自定义MembershipProvider

    我们需要有一个特殊的Provider,来读取自定义数据库,校验用户,并且把有关的数据都一起读出来

    请注意,作为演示,我只是实现了这个Provider的一个方法:ValidateUser.其他的方法都没有实现

        public class SECMembershipProvider:MembershipProvider
        {
    
            public override string ApplicationName
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public override bool ChangePassword(string username, string oldPassword, string newPassword)
            {
                throw new NotImplementedException();
            }
    
            public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
            {
                throw new NotImplementedException();
            }
    
            public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
            {
                throw new NotImplementedException();
            }
    
            public override bool DeleteUser(string username, bool deleteAllRelatedData)
            {
                throw new NotImplementedException();
            }
    
            public override bool EnablePasswordReset
            {
                get { throw new NotImplementedException(); }
            }
    
            public override bool EnablePasswordRetrieval
            {
                get { throw new NotImplementedException(); }
            }
    
            public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
            {
                throw new NotImplementedException();
            }
    
            public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
            {
                throw new NotImplementedException();
            }
    
            public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
            {
                throw new NotImplementedException();
            }
    
            public override int GetNumberOfUsersOnline()
            {
                throw new NotImplementedException();
            }
    
            public override string GetPassword(string username, string answer)
            {
                throw new NotImplementedException();
            }
    
            public override MembershipUser GetUser(string username, bool userIsOnline)
            {
                throw new NotImplementedException();
            }
    
            public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
            {
                throw new NotImplementedException();
            }
    
            public override string GetUserNameByEmail(string email)
            {
                throw new NotImplementedException();
            }
    
            public override int MaxInvalidPasswordAttempts
            {
                get { throw new NotImplementedException(); }
            }
    
            public override int MinRequiredNonAlphanumericCharacters
            {
                get { throw new NotImplementedException(); }
            }
    
            public override int MinRequiredPasswordLength
            {
                get { throw new NotImplementedException(); }
            }
    
            public override int PasswordAttemptWindow
            {
                get { throw new NotImplementedException(); }
            }
    
            public override MembershipPasswordFormat PasswordFormat
            {
                get { throw new NotImplementedException(); }
            }
    
            public override string PasswordStrengthRegularExpression
            {
                get { throw new NotImplementedException(); }
            }
    
            public override bool RequiresQuestionAndAnswer
            {
                get { throw new NotImplementedException(); }
            }
    
            public override bool RequiresUniqueEmail
            {
                get { throw new NotImplementedException(); }
            }
    
            public override string ResetPassword(string username, string answer)
            {
                throw new NotImplementedException();
            }
    
            public override bool UnlockUser(string userName)
            {
                throw new NotImplementedException();
            }
    
            public override void UpdateUser(MembershipUser user)
            {
                throw new NotImplementedException();
            }
    
            public override bool ValidateUser(string username, string password)
            {
                //这里可以实际读取数据库,对用户名和密码进行校验
                if (username == "007" && password == "password")
                {
    
                    var cookie = new HttpCookie(username + "_data");
    
                    cookie.Values.Add("displayName", "ares");
                    cookie.Values.Add("factory", "shanghai");
                    HttpContext.Current.Response.Cookies.Add(cookie);
    
                    return true;
    
                }
                return false;
            }
    
    
        }

    大家注意这个ValidateUser方法,我们除了校验用户之外,还可以将用户的displayName和factory读取出来,放在cookie里面。这是为了下一步做准备。

    第四步:注册使用这个MembershipProvider

            <membership defaultProvider="SECMembershipProvider">
                <providers>
                    <clear/>
            <add name="SECMembershipProvider" type="MvcApplicationSample.Extensions.SECMembershipProvider,MvcApplicationSample"/>
                    <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"/>
                </providers>
            </membership>

    第五步:修改HttpContext.User属性

    这是我们至关重要的一步。我们希望替换掉默认那个HttpContext.User。

    请注意,这个操作必须在一个特殊事件中来完成。请转到global.asax文件中,添加如下代码

            void Application_PostAuthenticateRequest(object sender, EventArgs e)
            {
                var app = (HttpApplication)sender;
                if (app.User.Identity.IsAuthenticated)
                {
                    var userName = app.User.Identity.Name;
                    var cookie = app.Request.Cookies[userName + "_data"];
                    var displayName = cookie.Values["displayName"];
                    var factory = cookie.Values["factory"];
    
                    HttpContext.Current.User= new Extensions.SECPrincipal(userName, displayName, factory);
                }
    
            }

    第六步:使用自定义的Principal

    我们在页面中,就可以很容易地使用自定义的这个Principal了。

            Welcome <b><%: Page.User.Identity.ToString() %>

    下面是一个最后的结果。这个项目是最近做给客户做MVC理论和实践课程中的一个范例。仅供参考

    image

    image

  • 相关阅读:
    揭秘Amazon反应速度超快的下拉菜单
    CSS3滤镜
    雅虎团队经验:网站页面性能优化的34条黄金守则
    10条影响CSS渲染速度的写法与建议
    前端优秀网站
    视频媒体播放,最好的 HTML 解决方法
    zen-coding for notepad++,前端最佳手写代码编辑器
    ASP.NET中IsPostBack详解
    w3c教程
    怎样才能成为优秀的前端开发工程师
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1870391.html
Copyright © 2011-2022 走看看