是否可以将 .ASPXAUTH 用于我自己的日志记录系统? [英] Is it possible to use .ASPXAUTH for my own logging system?

查看:32
本文介绍了是否可以将 .ASPXAUTH 用于我自己的日志记录系统?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一个 Web 应用程序,我从使用 ASP.NET Membership 切换到使用我自己的登录系统,它只是做这样的事情来将用户标记为登录:

Session["UserId"] = User.Id

是否可以将用户 ID 存储在 ASPXAUTH cookie 中,搭载其加密,而不是使用标准会话?

目标是使登录状态持续时间比会话更长,并且在浏览器和服务器重新启动时都能存活.

解决方案

更新:提供的原始答案是使用 MembershipProvider 的项目,答案本身对此进行了解释.我,提问者,没有使用它,所以我的问题的答案略有不同,但从这个答案中提取出来.对于任何关心的人,我将我的答案放在底部,并逐字逐句地保留原始答案,因为它包含很多价值.

<小时>

是的,您可以将 FormsAuthentication 用于您自己的策略.虽然 asp.net db 结构不适合您,但您可以提供 MembershipProvider 的简单实现以允许使用 Membership 基础结构.这两个功能没有结合,所以你可以决定什么适合你.

记住您的问题和一些评论,这里有一个可运行的示例,说明在不与默认实现和数据库模式结合的情况下利用提供者模型是多么简单.

为您自己的目的使用表单身份验证很简单.您只需要提供身份验证并设置您自己的票证 (cookie).

使用自定义成员资格几乎同样简单.您可以根据需要实施尽可能少或尽可能多的提供程序,以支持您想要使用的 asp.net 基础结构功能.

例如在下面的示例中,我展示了在登录过程中您可以简单地处理登录控件上的事件以验证凭据并设置票证.完成.

但我还将展示如何利用提供者模型和实现自定义成员资格提供者可以产生更强大、更清晰的代码.当我们在自定义成员资格提供程序中时,我实现了支持使用 Membership 子系统所需的最低限度,以提供对用户元数据的轻松访问,而无需编写您自己的基础架构.

只需将这些文件放到一个空项目中即可.

web.config

<小时>

<配置><system.web><编译调试=真"/><授权><deny users="?"/></授权><身份验证模式=表单"/><!--可选但推荐.通过自定义提供商离婚重用会员基础设施你来自 aspnetdb,但保留了所有你不需要的基础设施发展或维持--><membership defaultProvider="mine"><提供者><add name="mine" type="CustomAuthRepurposingFormsAuth.MyMembershipProvider"/></提供者></会员资格></system.web></配置>

Site1.Master

<小时>

<%@ Master Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="服务器"><title></title><asp:ContentPlaceHolder ID="head" runat="server"></asp:ContentPlaceHolder><身体><form id="form1" runat="server"><div><asp:LoginName ID="LoginName1" runat="server"/><asp:LoginStatus ID="LoginStatus1" runat="server"/><asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"></asp:ContentPlaceHolder>

</表单>

登录.aspx

<小时>

<%@ Page Title="" Language="C#" MasterPageFile="Site1.Master" %><%@ 导入命名空间="CustomAuthRepurposingFormsAuth" %><script runat="server">/** 如果您不想使用自定义成员资格提供程序进行身份验证* 只需将您的逻辑放在登录控件的处理程序中并删除* 来自配置的成员资格元素.这将需要一个非常非常* 引人注目的边缘案例激励我不使用自定义会员资格提供商.**///protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)//{////执行复杂的身份验证逻辑//e.Authenticated = Login1.UserName == Login1.Password;//}/**设置你的cookie,你就是金子*/void Authenticated(对象发送者,EventArgs e){//这是一个可以用于的任意数据槽???//在使用时记住 cookie 的大小.string userData = "任意数据";Response.Cookies.Add(TicketHelper.CreateAuthCookie(Login1.UserName, userData, Login1.RememberMeSet/*持久性cookie*/));}<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"></asp:内容><asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"><asp:Login ID="Login1" runat="server" OnLoggedIn="Authenticated" ></asp:登录>用户名==密码==已验证.<br/>例如:uid: me, pwd:me</asp:内容>

Default.aspx

<小时>

<%@ Page Title="" Language="C#" MasterPageFile="Site1.Master" %><%@ 导入命名空间="System.Security.Principal" %><%@ 导入命名空间="CustomAuthRepurposingFormsAuth" %><script runat="server">protected void Page_Load(object sender, EventArgs e){/** 你可以从 asp.net 免费获得*/HttpContext 页面 = HttpContext.Current;IIdentity identity = page.User.Identity;字符串用户名 = 身份.名称;bool authentication = identity.IsAuthenticated;//或使用 Request.IsAuthenticated 便捷访问器/** 你从表单认证中得到这个真的很便宜** 成本:验证凭据并设置您自己的票证*///此页面受 formauth 保护,因此身份实际上将//成为 FormsIdentity,您可以获取用户数据.//UserData 是存储_少量_数据的合适位置var fIdent = (FormsIdentity)identity;string userData = fIdent.Ticket.UserData;//所以,只使用表单 auth 这是你必须使用的LblAuthenticated.Text = page.User.Identity.IsAuthenticated.ToString();LblUserId.Text = page.User.Identity.Name;LblUserData.Text = 用户数据;/** 这是使用自定义成员资格提供程序和子类化* MembershipUser 类利用已建立的成熟基础设施** 这完全是可选的,您可以删除 web.config 中的 Membership 部分* 并删除 MyMembershipProvider 和 MyMembershipUser 并仅使用身份验证.**///获取自定义字段字符串 myCustomField = ((MyMembershipUser)Membership.GetUser()).MyCustomField;LblMembership.Text = myCustomField;}<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"></asp:内容><asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"><br/>已验证:<asp:Label ID="LblAuthenticated" runat="server" Text=""></asp:Label><br/>用户 ID:<asp:Label ID="LblUserId" runat="server" Text=""></asp:Label><br/>用户数据:<asp:Label ID="LblUserData" runat="server" Text=""></asp:Label><br/><br/>会员用户自定义字段:<asp:Label ID="LblMembership" runat="server" Text=""></asp:Label><br/></asp:内容>

CustomAuthClasses.cs

<小时>

使用系统;使用 System.Web;使用 System.Web.Security;命名空间 CustomAuthRepurposingFormsAuth{公共静态类 TicketHelper{///<总结>//////</总结>///<param name="userName"></param>///<param name="userData">注意 cookie 的大小,否则你会追逐鬼魂</param>///<param name="persistent"></param>///<returns></returns>public static HttpCookie CreateAuthCookie(string userName, string userData, bool persistent){发出的日期时间 = DateTime.Now;//formsAuth 不公开超时!?必须绕过//损坏的部分并继续前进..HttpCookie fooCookie = FormsAuthentication.GetAuthCookie("foo", true);int formsTimeout = Convert.ToInt32((fooCookie.Expires - DateTime.Now).TotalMinutes);日期时间到期 = DateTime.Now.AddMinutes(formsTimeout);字符串 cookiePath = FormsAuthentication.FormsCookiePath;var ticket = new FormsAuthenticationTicket(0, userName, issue, expire, true, userData, cookiePath);返回 CreateAuthCookie(票,到期,持久);}公共静态 HttpCookie CreateAuthCookie(FormsAuthenticationTicket 票证,DateTime 到期,布尔持久){string creamyFilling = FormsAuthentication.Encrypt(ticket);var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, creamyFilling){域 = FormsAuthentication.CookieDomain,路径 = FormsAuthentication.FormsCookiePath};如果(持续){cookie.Expires = 过期;}返回cookie;}}///<总结>///这是一个继承MembershipUser的例子///公开可能与您的相关联的任意数据///用户实现.//////您可以重新利用基础上的现有字段并添加您自己的字段.///只需对从您的返回的 MembershipUser 执行转换///MembershipProvider 实现///</总结>公共类 MyMembershipUser : MembershipUser{public MyMembershipUser(string providerName, string name, object providerUserKey, string email,字符串 passwordQuestion,字符串注释,bool isApproved,bool isLockedOut,日期时间创建日期、日期时间上次登录日期、日期时间上次活动日期、DateTime lastPasswordChangedDate, DateTime lastLockoutDate): 根据(providerName, name, providerUserKey, email, passwordQuestion, comment, isApproved, isLockedOut,creationDate、lastLoginDate、lastActivityDate、lastPasswordChangedDate、lastLockoutDate){}受保护的 MyMembershipUser(){}//例如不想使用 Profile,只能添加数据//比如说,从一个包含所有用户数据的平面记录公共字符串 MyCustomField { 获取;放;}}///<总结>///在最基本的层面上,实现 MembershipProvider 允许您///重用已建立的框架代码.在这种情况下,我们只提供服务///用于通过会员子系统进行登录控制和用户识别.///</总结>公共类 MyMembershipProvider : MembershipProvider{#region 为了使用已建立的身份验证和识别基础设施的最低实现///<总结>///如果您不想,您可以在登录逻辑中执行此操作///利用框架进行会员用户访问///</总结>public override bool ValidateUser(字符串用户名,字符串密码){返回用户名==密码;}公共覆盖 MembershipUser GetUser(string username, bool userIsOnline){/** 模拟去数据库获取数据*///会员用户不可为空的字段,重新调整用途或使用//隐含的空值,例如 DateTime.MinValue;var createdDate = new DateTime(2009, 10, 25);var lastLogin = new DateTime(2009, 10, 25);var lastActivity = new DateTime(2009, 10, 25);var lastPasswordChange = new DateTime(2009, 10, 25);var lastLockoutDate = new DateTime(2009, 10, 25);对象提供者用户密钥 = 3948;//例如用户主键./** 建立您的自定义用户并将其发送回 asp.net*///需要使用完整的构造函数来设置用户名和密钥var user = new MyMembershipUser(Name, username, providerUserKey, null, null, null, true, false, createdDate,上次登录,lastActivity、lastPasswordChange、lastLockoutDate){MyCustomField = "嘿"};返回用户;}#endregion#region 可选实现,具体取决于您想要利用的框架功能.public override bool EnablePasswordRetrieval{得到 { 抛出新的 NotImplementedException();}}public override bool EnablePasswordReset{得到 { 抛出新的 NotImplementedException();}}公共覆盖 bool RequiresQuestionAndAnswer{得到 { 抛出新的 NotImplementedException();}}公共覆盖字符串 ApplicationName{得到 { 抛出新的 NotImplementedException();}设置 { 抛出新的 NotImplementedException();}}公共覆盖 int MaxInvalidPasswordAttempts{得到 { 抛出新的 NotImplementedException();}}公共覆盖 int PasswordAttemptWindow{得到 { 抛出新的 NotImplementedException();}}公共覆盖 bool RequiresUniqueEmail{得到 { 抛出新的 NotImplementedException();}}公共覆盖 MembershipPasswordFormat PasswordFormat{得到 { 抛出新的 NotImplementedException();}}公共覆盖 int MinRequiredPasswordLength{得到 { 抛出新的 NotImplementedException();}}公共覆盖 int MinRequiredNonAlphanumericCharacters{得到 { 抛出新的 NotImplementedException();}}公共覆盖字符串 PasswordStrengthRegularExpression{得到 { 抛出新的 NotImplementedException();}}公共覆盖 MembershipUser GetUser(object providerUserKey, bool userIsOnline){抛出新的 NotImplementedException();}public override MembershipUser CreateUser(string username, string password, string email,字符串 passwordQuestion, 字符串 passwordAnswer, bool isApproved,对象 providerUserKey,退出 MembershipCreateStatus 状态){抛出新的 NotImplementedException();}public override bool ChangePasswordQuestionAndAnswer(string username, string password,字符串 newPasswordQuestion, 字符串 newPasswordAnswer){抛出新的 NotImplementedException();}公共覆盖字符串 GetPassword(字符串用户名,字符串答案){抛出新的 NotImplementedException();}public override bool ChangePassword(string username, string oldPassword, string newPassword){抛出新的 NotImplementedException();}公共覆盖字符串重置密码(字符串用户名,字符串答案){抛出新的 NotImplementedException();}公共覆盖无效更新用户(会员用户用户){抛出新的 NotImplementedException();}public override bool UnlockUser(string userName){抛出新的 NotImplementedException();}公共覆盖字符串 GetUserNameByEmail(字符串电子邮件){抛出新的 NotImplementedException();}public override bool DeleteUser(string username, bool deleteAllRelatedData){抛出新的 NotImplementedException();}公共覆盖 MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords){抛出新的 NotImplementedException();}公共覆盖 int GetNumberOfUsersOnline(){抛出新的 NotImplementedException();}公共覆盖 MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,out int totalRecords){抛出新的 NotImplementedException();}公共覆盖 MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,out int totalRecords){抛出新的 NotImplementedException();}#endregion}}

<小时>

实际使用的解决方案(作为使用 OpenID 的 ASP.NET MVC 项目):

我有一个 AccountController 用于登录和注销用户,这些方法都在那里.

#region 登录用户的方法.///<总结>///以创建我的 ASP.NET 会员系统的相同方式创建身份验证 cookie,希望持续时间超过 20 分钟.//////有关更多信息,请查看 http://stackoverflow.com/questions/2122831/is-it-possible-to-use-aspxauth-for-my-own-logging-system///</总结>///<param name="userId">登录用户的Id</param>/// Cookie 创建以将用户标记为已通过身份验证.</returns>私有静态 HttpCookie CreateAuthCookie(int userId) {发出的日期时间 = DateTime.Now;//formsAuth 不公开超时!?必须绕过损坏的部分并继续前进.HttpCookie fooCookie = FormsAuthentication.GetAuthCookie("foo", true);int formsTimeout = Convert.ToInt32((fooCookie.Expires - DateTime.Now).TotalMinutes);日期时间到期 = DateTime.Now.AddMinutes(formsTimeout);var ticket = new FormsAuthenticationTicket(0, userId.ToString(), issue, expire, true, "", FormsAuthentication.FormsCookiePath);返回 CreateAuthCookie(ticket, expire, true);}///<总结>///使用票证数据创建一个 auth cookie.///</总结>///<param name="ticket">Ticket 包含将用户标记为已通过身份验证的数据.</param>///<param name="expiration">cookie 的有效期.</param>///<param name="persistent">是否持久化</param>/// Cookie 创建以将用户标记为已通过身份验证.</returns>私有静态 HttpCookie CreateAuthCookie(FormsAuthenticationTicket 票证,DateTime 到期,布尔持久){字符串 encryptedAuthData = FormsAuthentication.Encrypt(ticket);var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedAuthData) {域 = FormsAuthentication.CookieDomain,路径 = FormsAuthentication.FormsCookiePath};如果(持久){cookie.Expires = 过期;}返回cookie;}///<总结>///使身份验证 cookie 过期,从而有效地注销用户.///</总结>私有无效 ExpireAuthCookie() {var cookie = new HttpCookie(FormsAuthentication.FormsCookieName);cookie.Expires = DateTime.Now.AddDays(-1);Response.Cookies.Add(cookie);}#endregion

For a web application I switched from using ASP.NET Membership to using my own log in system which just does something like this to mark a user as logged in:

Session["UserId"] = User.Id

Is it possible to store the user id in the ASPXAUTH cookie, piggybacking on its encryption, instead of using the standard session?

The goal is for the logged in state to last longer than a session and survive both browser and server restarts.

解决方案

Update: The original answer provided was with a project using MembershipProvider and it's explained in the answer itself. I, the asker, am not using it, so the answer to my problem was slightly different but extracted from this answer. I'm putting my answer at the bottom for anyone that cares and leaving the original verbatim, as it contains a lot of value.


Yes, you can use FormsAuthentication for your own strategy. And while the asp.net db structure does not suit you, you may provide a simple implementation of MembershipProvider to allow use of the Membership infrastructure. These two functionalities are not married so you may decide what fits for you.

Keeping in mind your question and some of the comments, here is a runnable example of how simple it is to leverage the provider model without being married to the default implementations and db schemas.

Using forms auth for your own purposes is simple. You just need to provide authentication and set your own ticket (cookie).

Using custom membership is almost as simple. You can implement as little or as much of the provider as you need to support the asp.net infrastructure features that you would like to employ.

e.g. in the sample below, I show that in the login process you may simply handle an event on the login control to validate credentials and the set the ticket. Done.

But I will also show how leveraging the provider model and implementing a custom membership provider can result in stronger, cleaner code. While we are in the custom membership provider I implement the minimum necessary to support using the Membership subsystem to provide easy access to a user's meta data without the need to write your own infrastructure.

Just drop these files into an empty project.

web.config


<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true"/>
    <authorization>
      <deny users="?"/>
    </authorization>
    <authentication mode="Forms"/>
    <!-- 
    optional but recommended. reusing the membership infrastructure via custom provider divorces 
    you from the aspnetdb but retains all of the baked in infrastructure which you do not have to 
    develop or maintain
    -->
    <membership defaultProvider="mine">
      <providers>
        <add name="mine" type="CustomAuthRepurposingFormsAuth.MyMembershipProvider"/>
      </providers>
    </membership>
  </system.web>
</configuration>

Site1.Master


<%@ Master Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:LoginName ID="LoginName1" runat="server" />
        <asp:LoginStatus ID="LoginStatus1" runat="server" />
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

Login.aspx


<%@ Page Title="" Language="C#" MasterPageFile="Site1.Master" %>
<%@ Import Namespace="CustomAuthRepurposingFormsAuth" %>
<script runat="server">

    /*
     * If you don't want to use a custom membership provider to authenticate
     * simply place your logic in the login control's handler and remove the 
     * membership element from config. It would have to take a very very 
     * compelling edge case to motivate me to not use a custom membership provider.
     * 
     */

    //protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
    //{
    //    // perform mindbendingly complex authentication logic
    //    e.Authenticated = Login1.UserName == Login1.Password;
    //}


    /*
     * set your cookie and you are golden
     */
    void Authenticated(object sender, EventArgs e)
    {
        // this is an arbitrary data slot you can use for ???
        // keep cookie size in mind when using it.
        string userData = "arbitraryData";
        Response.Cookies.Add(TicketHelper.CreateAuthCookie(Login1.UserName, userData, Login1.RememberMeSet /*persistent cookie*/));
    }

</script>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <asp:Login ID="Login1" runat="server" OnLoggedIn="Authenticated" >
    </asp:Login>
    username==password==authenticated. <br />e.g.: uid: me, pwd:me
</asp:Content>

Default.aspx


<%@ Page Title="" Language="C#" MasterPageFile="Site1.Master" %>

<%@ Import Namespace="System.Security.Principal" %>
<%@ Import Namespace="CustomAuthRepurposingFormsAuth" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        /*
         * you get this for free from asp.net
         */

        HttpContext page = HttpContext.Current;

        IIdentity identity = page.User.Identity;
        string username = identity.Name;
        bool authenticate = identity.IsAuthenticated;
        // or use the Request.IsAuthenticated convenience accessor

        /* 
         * you get this really cheap from forms auth
         * 
         * cost: validating credentials and setting your own ticket
         */

        // this page is protected by formsauth so the identity will actually 
        // be a FormsIdentity and you can get at the user data.
        // UserData is an appropriate place to store _small_ amounts of data
        var fIdent = (FormsIdentity)identity;
        string userData = fIdent.Ticket.UserData;


        // so, using only forms auth this is what you have to work with
        LblAuthenticated.Text = page.User.Identity.IsAuthenticated.ToString();
        LblUserId.Text = page.User.Identity.Name;
        LblUserData.Text = userData;

        /* 
         * this is an example of using a custom membership provider and subclassing the 
         * MembershipUser class to take advantage of the established mature infrastructure
         * 
         * this is entirely optional, you can delete the Membership section in web.config 
         * and delete MyMembershipProvider and MyMembershipUser and just use the authentication.
         * 
         */

        // get the custom field
        string myCustomField = ((MyMembershipUser)Membership.GetUser()).MyCustomField;
        LblMembership.Text = myCustomField;
    }        
</script>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <br />
    Authenticated:<asp:Label ID="LblAuthenticated" runat="server" Text=""></asp:Label><br />
    UserId:<asp:Label ID="LblUserId" runat="server" Text=""></asp:Label><br />
    UserData:<asp:Label ID="LblUserData" runat="server" Text=""></asp:Label><br />
    <br />
    Membership User Custom Field:<asp:Label ID="LblMembership" runat="server" Text=""></asp:Label><br />
</asp:Content>

CustomAuthClasses.cs


using System;
using System.Web;
using System.Web.Security;

namespace CustomAuthRepurposingFormsAuth
{
    public static class TicketHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userData">be mindful of the cookie size or you will be chasing ghosts</param>
        /// <param name="persistent"></param>
        /// <returns></returns>
        public static HttpCookie CreateAuthCookie(string userName, string userData, bool persistent)
        {
            DateTime issued = DateTime.Now;
            // formsAuth does not expose timeout!? have to hack around the
            // spoiled parts and keep moving..
            HttpCookie fooCookie = FormsAuthentication.GetAuthCookie("foo", true);
            int formsTimeout = Convert.ToInt32((fooCookie.Expires - DateTime.Now).TotalMinutes);

            DateTime expiration = DateTime.Now.AddMinutes(formsTimeout);
            string cookiePath = FormsAuthentication.FormsCookiePath;

            var ticket = new FormsAuthenticationTicket(0, userName, issued, expiration, true, userData, cookiePath);
            return CreateAuthCookie(ticket, expiration, persistent);
        }

        public static HttpCookie CreateAuthCookie(FormsAuthenticationTicket ticket, DateTime expiration, bool persistent)
        {
            string creamyFilling = FormsAuthentication.Encrypt(ticket);
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, creamyFilling)
                             {
                                 Domain = FormsAuthentication.CookieDomain,
                                 Path = FormsAuthentication.FormsCookiePath
                             };
            if (persistent)
            {
                cookie.Expires = expiration;
            }

            return cookie;
        }
    }

    /// <summary>
    /// This is an example of inheriting MembershipUser to
    /// expose arbitrary data that may be associated with your
    /// user implementation.
    /// 
    /// You may repurpose existing fields on the base and add your own.
    /// Just perform a cast on the MembershipUser returned from your
    /// MembershipProvider implementation
    /// </summary>
    public class MyMembershipUser : MembershipUser
    {
        public MyMembershipUser(string providerName, string name, object providerUserKey, string email,
                                string passwordQuestion, string comment, bool isApproved, bool isLockedOut,
                                DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate,
                                DateTime lastPasswordChangedDate, DateTime lastLockoutDate)
            : base(
                providerName, name, providerUserKey, email, passwordQuestion, comment, isApproved, isLockedOut,
                creationDate, lastLoginDate, lastActivityDate, lastPasswordChangedDate, lastLockoutDate)
        {
        }

        protected MyMembershipUser()
        {
        }

        // e.g. no desire to use Profile, can just add data
        // say, from a flat record containing all user data
        public string MyCustomField { get; set; }
    }

    /// <summary>
    /// At the most basic level, implementing a MembershipProvider allows you to
    /// reuse established framework code. In this case, we just provide services
    /// for the Login control and user identification via Membership subsystem.
    /// </summary>
    public class MyMembershipProvider : MembershipProvider
    {
        #region Minimum implementation in order to use established authentication and identification infrastructure

        /// <summary>
        /// You can just do this in the login logic if you do not want
        /// leverage framework for membership user access
        /// </summary>
        public override bool ValidateUser(string username, string password)
        {
            return username == password;
        }


        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            /*
             * Simulate going to the DB to get the data
             */

            // membership user non nullable fields, repurpose or use
            // implied null value e.g DateTime.MinValue;

            var createdDate = new DateTime(2009, 10, 25);
            var lastLogin = new DateTime(2009, 10, 25);
            var lastActivity = new DateTime(2009, 10, 25);
            var lastPasswordChange = new DateTime(2009, 10, 25);
            var lastLockoutDate = new DateTime(2009, 10, 25);

            object providerUserKey = 3948; // e.g. user primary key. 


            /*
             * build your custom user and send it back to asp.net
             */

            // need to use the full constructor to set the username and key
            var user = new MyMembershipUser(Name, username, providerUserKey, null, null, null, true, false, createdDate,
                                            lastLogin,
                                            lastActivity, lastPasswordChange, lastLockoutDate)
                           {
                               MyCustomField = "Hey"
                           };

            return user;
        }

        #endregion

        #region Optional implementations depending on the framework features you would like to leverage.

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override string ApplicationName
        {
            get { throw new NotImplementedException(); }
            set { throw new NotImplementedException(); }
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            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 ChangePasswordQuestionAndAnswer(string username, string password,
                                                             string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }


        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            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 MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
                                                                 out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
                                                                  out int totalRecords)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}


Solution actually used (in as ASP.NET MVC project using OpenID):

I have an AccountController which I use to log users in and out and these methods are there.

#region Methods to log in a user.
/// <summary>
/// Create the auth cookie in the same way it is created my ASP.NET Membership system, hopefully lasting for more than 20 minutes.
/// 
/// For more information check out http://stackoverflow.com/questions/2122831/is-it-possible-to-use-aspxauth-for-my-own-logging-system
/// </summary>
/// <param name="userId">Id of the user that is logged in</param>
/// <returns>Cookie created to mark the user as authenticated.</returns>
private static HttpCookie CreateAuthCookie(int userId) {
  DateTime issued = DateTime.Now;
  // formsAuth does not expose timeout!? have to hack around the spoiled parts and keep moving..
  HttpCookie fooCookie = FormsAuthentication.GetAuthCookie("foo", true);
  int formsTimeout = Convert.ToInt32((fooCookie.Expires - DateTime.Now).TotalMinutes);

  DateTime expiration = DateTime.Now.AddMinutes(formsTimeout);

  var ticket = new FormsAuthenticationTicket(0, userId.ToString(), issued, expiration, true, "", FormsAuthentication.FormsCookiePath);
  return CreateAuthCookie(ticket, expiration, true);
}

/// <summary>
/// Create an auth cookie with the ticket data.
/// </summary>
/// <param name="ticket">Ticket containing the data to mark a user as authenticated.</param>
/// <param name="expiration">Expriation date for the cookie.</param>
/// <param name="persistent">Whether it's persistent or not.</param>
/// <returns>Cookie created to mark the user as authenticated.</returns>
private static HttpCookie CreateAuthCookie(FormsAuthenticationTicket ticket, DateTime expiration, bool persistent) {
  string encryptedAuthData = FormsAuthentication.Encrypt(ticket);
  var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedAuthData) {
    Domain = FormsAuthentication.CookieDomain,
    Path = FormsAuthentication.FormsCookiePath
  };
  if (persistent) {
    cookie.Expires = expiration;
  }

  return cookie;
}

/// <summary>
/// Expire the authentication cookie effectively loging out a user.
/// </summary>
private void ExpireAuthCookie() {
  var cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
  cookie.Expires = DateTime.Now.AddDays(-1);
  Response.Cookies.Add(cookie);
}
#endregion

这篇关于是否可以将 .ASPXAUTH 用于我自己的日志记录系统?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆