代码之家  ›  专栏  ›  技术社区  ›  Niels Bosma

查看我的ASP.NET身份验证代码

  •  2
  • Niels Bosma  · 技术社区  · 16 年前

    我在ASP.NET中的身份验证有一些问题。我没有使用.NET中的大多数内置身份验证。

    我从使用Internet Explorer的用户那里得到了一些抱怨(任何版本-也可能影响其他浏览器),他们的登录过程正在进行,但是当重定向时,他们没有经过身份验证,会被退回到loginpage(如果登录,则需要进行身份验证检查,如果不重定向回loginpage)。这会是cookie问题吗?

    是否需要检查用户是否启用了cookie?

    如果您有一个自定义成员表并且不想使用ASP.NET登录控件,那么构建身份验证的最佳方法是什么?

    这里是我的当前代码:

    using System;
    using System.Linq;
    using MyCompany;
    using System.Web;
    using System.Web.Security;
    using MyCompany.DAL;
    using MyCompany.Globalization;
    using MyCompany.DAL.Logs;
    using MyCompany.Logging;
    
    namespace MyCompany
    {
    
        public class Auth
        {
    
            public class AuthException : Exception
            {
                public int StatusCode = 0;
                public AuthException(string message, int statusCode) : base(message) { StatusCode = statusCode;  }
            }
    
            public class EmptyEmailException : AuthException
            {
                public EmptyEmailException() : base(Language.RES_ERROR_LOGIN_CLIENT_EMPTY_EMAIL, 6) { }
            }
    
            public class EmptyPasswordException : AuthException
            {
                public EmptyPasswordException() : base(Language.RES_ERROR_LOGIN_CLIENT_EMPTY_PASSWORD, 7) { }
            }
    
            public class WrongEmailException : AuthException
            {
                public WrongEmailException() : base(Language.RES_ERROR_LOGIN_CLIENT_WRONG_EMAIL, 2) { }
            }
    
            public class WrongPasswordException : AuthException
            {
                public WrongPasswordException() : base(Language.RES_ERROR_LOGIN_CLIENT_WRONG_PASSWORD, 3) { }
            }
    
            public class InactiveAccountException : AuthException
            {
                public InactiveAccountException() : base(Language.RES_ERROR_LOGIN_CLIENT_INACTIVE_ACCOUNT, 5) { }
            }
    
            public class EmailNotValidatedException : AuthException
            {
                public EmailNotValidatedException() : base(Language.RES_ERROR_LOGIN_CLIENT_EMAIL_NOT_VALIDATED, 4) { }
            }
    
            private readonly string CLIENT_KEY = "9A751E0D-816F-4A92-9185-559D38661F77";
    
            private readonly string CLIENT_USER_KEY = "0CE2F700-1375-4B0F-8400-06A01CED2658";
    
            public Client Client
            {
                get
                {
                    if(!IsAuthenticated) return null;
                    if(HttpContext.Current.Items[CLIENT_KEY]==null)
                    {
                        HttpContext.Current.Items[CLIENT_KEY] = ClientMethods.Get<Client>((Guid)ClientId); 
                    }
                    return (Client)HttpContext.Current.Items[CLIENT_KEY];
                }
            }
    
            public ClientUser ClientUser
            {
                get
                {
                    if (!IsAuthenticated) return null;
                    if (HttpContext.Current.Items[CLIENT_USER_KEY] == null)
                    {
                        HttpContext.Current.Items[CLIENT_USER_KEY] = ClientUserMethods.GetByClientId((Guid)ClientId);
                    }
                    return (ClientUser)HttpContext.Current.Items[CLIENT_USER_KEY];
                }
            }
    
            public Boolean IsAuthenticated { get; set; }
    
            public Guid? ClientId { 
                get 
                {
                    if (!IsAuthenticated) return null;
                    return (Guid)HttpContext.Current.Session["ClientId"];
                } 
            }
    
            public Guid? ClientUserId { 
                get {
                    if (!IsAuthenticated) return null;
                    return ClientUser.Id;
                } 
            }
    
            public int ClientTypeId { 
                get {
                    if (!IsAuthenticated) return 0;
                    return Client.ClientTypeId;
                } 
            }
    
            public Auth()
            {
                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    IsAuthenticated = true;
                }
            }
    
            public void RequireClientOfType(params int[] types)
            {
                if (!(IsAuthenticated && types.Contains(ClientTypeId)))
                {
                    HttpContext.Current.Response.Redirect((new UrlFactory(false)).GetHomeUrl(), true);
                }
            }
    
            public void Logout()
            {
                Logout(true);
            }
    
            public void Logout(Boolean redirect)
            {
                FormsAuthentication.SignOut();
                IsAuthenticated = false;
                HttpContext.Current.Session["ClientId"] = null;
                HttpContext.Current.Items[CLIENT_KEY] = null;
                HttpContext.Current.Items[CLIENT_USER_KEY] = null;
                if(redirect) HttpContext.Current.Response.Redirect((new UrlFactory(false)).GetHomeUrl(), true);
            }
    
            public void Login(string email, string password, bool autoLogin)
            {
                Logout(false);
    
                email = email.Trim().ToLower();
                password = password.Trim();
    
                int status = 1;
    
                LoginAttemptLog log = new LoginAttemptLog { AutoLogin = autoLogin, Email = email, Password = password };
    
                try
                {
                    if (string.IsNullOrEmpty(email)) throw new EmptyEmailException();
    
                    if (string.IsNullOrEmpty(password)) throw new EmptyPasswordException();
    
                    ClientUser clientUser = ClientUserMethods.GetByEmailExcludingProspects(email);
    
                    if (clientUser == null) throw new WrongEmailException();
    
                    if (!clientUser.Password.Equals(password)) throw new WrongPasswordException();
    
                    Client client = clientUser.Client;
    
                    if (!(bool)client.PreRegCheck) throw new EmailNotValidatedException();
    
                    if (!(bool)client.Active || client.DeleteFlag.Equals("y")) throw new InactiveAccountException();
    
                    FormsAuthentication.SetAuthCookie(client.Id.ToString(), true);
                    HttpContext.Current.Session["ClientId"] = client.Id;
    
                    log.KeyId = client.Id;
                    log.KeyEntityId = ClientMethods.GetEntityId(client.ClientTypeId);
                }
                catch (AuthException ax)
                {
                    status = ax.StatusCode;
                    log.Success = status == 1;
                    log.Status = status;
                }
                finally
                {
                    LogRecorder.Record(log);
                }
    
            }
    
        }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   Krunal    16 年前

    尝试使用内置的ASP.NET 窗体身份验证 (会员)。

    您可以从这些视频中学习:

    Link1 Link2

    如果要自定义,请观看此视频:

    Link

        2
  •  8
  •   Stephen Kennedy annamataws    7 年前

    经典案例 过度设计 认证机制,除此之外,设计也很糟糕。

    • 异常应该在auth类之外,但驻留在同一个命名空间中。 如果微软创建了这样的异常,.NET框架会是什么样子? 总是保持简单,愚蠢( )似乎您需要模块化代码。 尽量简单而模块化 .

    • 您的身份验证客户端密钥是静态的 魔法值 你要把它们和你的组件一起装运。使用 安全字符串 而不是 只读字符串 . 任何人都可以使用反射镜来控制它。你如何维持改变广告安全?

    • 您的代码直接引用当前代码 请求上下文 对象,实际上您可以在将使用此对象的客户端代码中传递当前上下文对象的引用。

    • 要求输入类型 是int[]——你为什么要这样做?我相信如果需要的话,它可能是一个枚举或者一个不变的结构。

    • 您已经在使用 表格认证 在login()和logout()中,这足以替换整个auth。如果你最终要用formsauthnettion来处理auth,为什么你要重新发明轮子呢?

    • 是的,如果你不能修改这个设计,请使用 FXCOP /至少要避免使用意大利面条代码。

    • 你也可以使类认证为 静止的 并公开功能,如FormsAuthentication。并将其从auth重命名为 认证 .

    这是 http://thedailywtf.com/