C# 忘记密码URL

C# 忘记密码URL,c#,asp.net,url,C#,Asp.net,Url,我有一个使用asp.net登录控件的web应用程序。此外,我还为用户使用密码恢复控件来恢复其密码。一旦用户在恢复控件中输入完他们的详细信息,将向用户的电子邮件地址发送一封包含验证URL的电子邮件。单击URL后,它将引导用户进入我的web应用程序的UserProfile,在该应用程序中,它允许用户更改密码 现在的问题是,因为我将访问规则设置为UserProfile.aspx以拒绝匿名用户,所以当我从URL重定向到UserProfile.aspx页面时,它会将我指向登录页面(系统将我识别为匿名用户)

我有一个使用asp.net登录控件的web应用程序。此外,我还为用户使用密码恢复控件来恢复其密码。一旦用户在恢复控件中输入完他们的详细信息,将向用户的电子邮件地址发送一封包含验证URL的电子邮件。单击URL后,它将引导用户进入我的web应用程序的UserProfile,在该应用程序中,它允许用户更改密码

现在的问题是,因为我将访问规则设置为UserProfile.aspx以拒绝匿名用户,所以当我从URL重定向到UserProfile.aspx页面时,它会将我指向登录页面(系统将我识别为匿名用户)

为什么会这样?单击URL(包括所有用户信息)后,是否有任何地方可以直接进入userprofile页面

URL如下所示:

http://localhost:1039/Members/UserProfile.aspx?ID=56f74cc7-7680-4f1b-9207-0ab8dad63cad 
其中URL的最后一部分实际上是用户ID

以下是userprofile aspx的代码:

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
              ConnectionString="<%$ ConnectionStrings:ASPNETDBConnectionString1 %>" 
              SelectCommand="SELECT aspnet_Membership.Email, Details.CustName, Details.CustNum, Details.CustRole, Details.CustStatus, Details.PName, Details.PEmail, Details.PRole, Details.WedDate, aspnet_Users.UserName, Details.UserId FROM Details INNER JOIN aspnet_Membership ON Details.UserId = aspnet_Membership.UserId INNER JOIN aspnet_Users ON aspnet_Membership.UserId = aspnet_Users.UserId WHERE (Details.UserId = @UserId)" 


              UpdateCommand="update Details SET CustName = @CustName, CustNum = @CustNum, CustRole = @CustRole, CustStatus = @CustStatus, PName = @PName, PEmail = @PEmail, PRole = @PRole, WedDate = @WedDate WHERE [UserId] = @UserId

                            Update aspnet_Membership Set Email= @email WHERE [UserId] = @UserId"

              DeleteCommand= "DELETE FROM Details WHERE UserId = @UserId;"> 

              <DeleteParameters>
                  <asp:ControlParameter ControlID="lblHidden" Name="UserId" PropertyName="Text" 
                      Type="String" />
              </DeleteParameters>

              <SelectParameters>
                  <asp:ControlParameter ControlID="lblHidden" Name="UserId" PropertyName="Text" />

              </SelectParameters>

              <UpdateParameters>
                  <asp:Parameter Name="CustName" />
                  <asp:Parameter Name="CustNum" />
                  <asp:Parameter Name="CustRole" />
                  <asp:Parameter Name="CustStatus" />
                  <asp:Parameter Name="PName" />
                  <asp:Parameter Name="PEmail" />
                  <asp:Parameter Name="PRole" />
                  <asp:Parameter Name="WedDate" />
                  <asp:Parameter Name="UserId" />
                  <asp:Parameter Name="email" />
              </UpdateParameters>


          </asp:SqlDataSource>
          <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" 
              DataSourceID="SqlDataSource1" Height="50px" Width="125px">
              <Fields>
                  <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
                  <asp:BoundField DataField="CustName" HeaderText="CustName" 
                      SortExpression="CustName" />
                  <asp:BoundField DataField="CustNum" HeaderText="CustNum" 
                      SortExpression="CustNum" />
                  <asp:BoundField DataField="CustRole" HeaderText="CustRole" 
                      SortExpression="CustRole" />
                  <asp:BoundField DataField="CustStatus" HeaderText="CustStatus" 
                      SortExpression="CustStatus" />
                  <asp:BoundField DataField="PName" HeaderText="PName" SortExpression="PName" />
                  <asp:BoundField DataField="PEmail" HeaderText="PEmail" 
                      SortExpression="PEmail" />
                  <asp:BoundField DataField="PRole" HeaderText="PRole" SortExpression="PRole" />
                  <asp:BoundField DataField="WedDate" HeaderText="WedDate" 
                      SortExpression="WedDate" />
                  <asp:BoundField DataField="UserName" HeaderText="UserName" 
                      SortExpression="UserName" />
                  <asp:BoundField DataField="UserId" HeaderText="UserId" 
                      SortExpression="UserId" />
                  <asp:CommandField ShowEditButton="True" />
              </Fields>
          </asp:DetailsView>
          <asp:Label ID="lblHidden" runat="server" Text="Label" Visible="False"></asp:Label>



          <asp:Button ID="btnDelete" runat="server" onclick="btnDelete_Click" 
              Text="Delete" />

第二,有没有办法设置URL的到期日?如果第二次单击URL,则不会将用户重定向到任何位置。我看到很多帖子,大多数都建议在数据库中添加一列。有没有其他方法可以在不接触数据库的情况下设置过期时间

您可以尝试允许匿名用户进入您的userprofile页面,方法是将以下内容添加到
标记内的web.config中

  <location path="userProfile.aspx">
    <system.web>
      <authorization>
        <allow users="?"/>
      </authorization>
    </system.web>
  </location>

考虑为changepassword链接设置一个单独的页面。使此页具有唯一标识符。此标识符只能使用一次,有到期日期,并且特定于该用户。将此页面公开:

<location path="changepassword.aspx">
 <system.web>
   <authorization>
     <allow users="*"/>
   </authorization>
 </system.web>
</location>

请求页面时,如果标识符已过期,则不允许页面运行。一旦密码被更改,请使标识符无效-要么删除它,要么将过期日期设置为过去的某个日期(例如现在)。

这不是对所问问题的直接回答,而是对密码重置工具结构的更一般性评论

当编写这个功能时,我会做一些不同的事情

访问个人资料页面或更改密码?

首先,如果用户只需要更改密码,他们不需要访问用户配置文件页面,只需要更改密码页面。我会直接把他们带到“更改密码”页面,并将其特定于pasword重置功能,从而使其匿名可用,不会出现任何问题

为什么不对他们进行身份验证,然后将他们发送到个人资料页面?

另一种选择是,与其乱搞匿名访问,只需自动登录即可。该url将导致一个登录页面,该页面将自动登录给定用户(毕竟您拥有所有用户详细信息)。然后,他们可以重定向到个人资料页面,他们不再是匿名的,所以一切都好

纯文本用户ID的问题

您需要使用更好的令牌。如果有人可以找到另一个用户的用户id(如果您单击查看用户公共配置文件,它可能会显示在url中),那么他们可以更改该用户的密码。我相信你也知道,这并不酷

我使用什么来代替明文用户ID?

随机标记

这两种方法是创建存储在数据库中的随机令牌,然后在加载页面时验证它们。这样,当您想使它们失效时,只需更改数据库中的某些内容,就可以很容易地使它们失效。您只需在DB中存储一个随机令牌(我可能会选择长度约为16个字符的base64编码字符串,有效的随机性为96位)以及任何必要的信息(例如用户ID、创建日期(或到期日期)等)。如果您希望它是一次使用,您可以在验证一次后将该令牌从数据库中清除(或者标记一个字段以表明其已被使用或任何数量的其他替代方案)

加密令牌

不涉及数据库的更安全的方法是创建一个可以传递给用户的加密令牌。此令牌可以包含用户ID和创建令牌的时间(以及您想要的任何其他信息),并将其放入电子邮件中并被遗忘。因为它是加密的数据,而不是回发上的随机令牌,而不是通过数据库进行验证,所以您只需将给定的令牌解密给fidn用户以及该令牌的使用年限

如果您想在不访问数据库的情况下一次性使用它们,这有点棘手,但我可能会将生成的令牌存储在服务器应用程序字典中,如果该令牌不在其中,则该令牌无效,一旦使用,您就将其从存储的列表中删除。您还可以定期清理旧代币,以确保不会存储太多垃圾。这种方法还有一个缺点,即如果重新启动应用程序,您将清除令牌列表,从而使它们全部无效。这只是一个问题,如果你需要他们是一次性的。就我个人而言,我会让他们在您认为合适的任何时间段内用一个令牌重置所有他们想要的密码。:)

关于原始场景中纯文本用户ID的另一个警告

我再怎么强调也不过分,在url中以明文形式输入用户ID作为传递的唯一信息时,您需要多么小心。一旦有人发现另一个人的用户ID,他们的帐户就会被有效地破坏。他们只需将该用户ID输入url,就可以更改密码


即使你现在没有任何地方可以公开其他人的用户ID,你也必须100%确保将来也不会公开,这在实践中是不可能保证的。

你在应用程序中创建了角色吗?嗨,我没有创建任何角色
<location path="changepassword.aspx">
 <system.web>
   <authorization>
     <allow users="*"/>
   </authorization>
 </system.web>
</location>
PK | Identifier | UserID                               | expires
1  | abcd       | ffffffff-ffff-ffff-ffff-ffffffffffff | 16-jul-2012 18:26