2023-02-16 284
对于Web应用程序,我将从使用ASP.NET成员身份切换到使用我自己的登录系统,该系统只是这样做的,以便将用户标记为登录:
Session["UserId"] = User.Id
是否可以将用户ID存储在aspxauth cookie中,捎带其加密,而不是使用标准会话?
目标是为了登录状态持续时间超过会话,并在两个浏览器和服务器重新启动时存活.
更新:提供的原始答案是使用MembershipProvider的项目,它在答案本身中解释.我,问员,我不使用它,所以我问题的答案略有不同,但从这个答案中提取了略有不同.我在底部把答案放在底部,因为它含有大量的价值.
是的,您可以为自己的策略使用FormsAuthentication.虽然ASP.NET DB结构不适合您,但您可能会提供MembershipProvider的简单实现,以允许使用隶属资格基础架构.这两种功能没有结婚,所以你可以决定你的适合.
请识别您的问题和一些评论,这里是一个可追溯的例子,它是利用提供商模型的简单而不与默认实现和数据库模式结婚.
使用Forms Auth以您自己的目的很简单.您只需要提供身份验证并设置自己的票证(Cookie).
使用自定义成员几乎是简单的.您可以尽可能少地实现提供者,因为您需要支持您想要使用的ASP.NET基础架构功能.
e .g.在下面的示例中,我显示在登录过程中,您可以简单地处理登录控件的事件以验证凭据和设置票证.完成.
但我还将显示如何利用提供商模型和实现自定义会员提供商可以导致更强大的更清晰的代码.虽然我们在自定义会员提供程序中,我实施了使用隶属子系统支持支持的最小必要,以便在不需要编写自己的基础架构的情况下轻松访问用户的元数据.
只将这些文件丢弃到一个空项目中.
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
}
}
解决方案实际使用(以ASP.NET MVC项目使用OpenID):
我有一个账户控制器,我用来登录用户,并且这些方法在存在.
#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 cookie完全将认证令牌分开,它是它使用的原因之一.如果您的系统使用会话,那么它真的与表单身份验证正在尝试的次数.
如果一切都在会话中,那么真的,您真的不需要身份验证票证,假设会话是安全的.
以上所述是小编给大家介绍的是否可以使用.ASPXAUTH作为我自己的日志系统?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/33833.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态