2012-07-16 70 views
5

Tôi có một ứng dụng web sử dụng điều khiển đăng nhập asp.net. Ngoài ra, tôi cũng sử dụng một điều khiển phục hồi mật khẩu cho người dùng để khôi phục mật khẩu của họ. Khi người dùng đã nhập xong thông tin cụ thể của họ trong điều khiển khôi phục, một email chứa URL xác minh sẽ được gửi đến địa chỉ email của người dùng. Khi nhấp vào URL, nó sẽ hướng người dùng vào UserProfile của ứng dụng web của tôi, bên trong, nó cho phép người dùng thay đổi mật khẩu của họ. Bây giờ vấn đề là, bởi vì tôi thiết lập một quy tắc truy cập để UserProfile.aspx để từ chối người dùng ẩn danh, khi tôi chuyển hướng từ URL vào trang UserProfile.aspx, nó đưa tôi đến LoginPage thay vào đó (hệ thống nhận ra tôi là người dùng ẩn danh).Quên mật khẩu URL

Tại sao lại như vậy? Có bất kỳ nơi nào mà tôi có thể chuyển hướng trực tiếp đến trang userprofile khi URL được nhấp (bao gồm tất cả thông tin người dùng) không?

Diện mạo URL như sau:

http://localhost:1039/Members/UserProfile.aspx?ID=56f74cc7-7680-4f1b-9207-0ab8dad63cad 

Trường hợp phần cuối cùng của URL thực sự là userId.

Đây là mã cho 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" /> 

Đây là đoạn mã sau:

protected void Page_Load(object sender, EventArgs e) 
    { 
     MembershipUser currentUser = Membership.GetUser(); 
     lblHidden.Text = currentUser.ProviderUserKey.ToString(); 
    } 

    protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e) 
    { 
     // Get a reference to the currently logged on user 
     MembershipUser currentUser = Membership.GetUser(); 

     // Determine the currently logged on user's UserId value 
     // Assign the currently logged on user's UserId to the @UserId parameter 
     //access the parameter value using e.Command.Parameters 
     //programmatically set the @UserId: 
     e.Command.Parameters["@UserId"].Value = currentUser.ProviderUserKey.ToString(); 



    } 
    protected void btnDelete_Click(object sender, EventArgs e) 
    { 

     SqlConnection connection = new SqlConnection(); 
     connection.ConnectionString = ConfigurationManager.ConnectionStrings["ASPNETDBConnectionString1"].ConnectionString; 
     SqlCommand cmd = new SqlCommand(); 
     SqlCommand cmd1 = new SqlCommand(); 
     string userId = lblHidden.Text; 

     cmd.Connection = connection; 
     cmd.CommandText = "DELETE FROM Details WHERE UserId ='" + userId + "'"; 


     cmd1.Connection = connection; 
     cmd1.CommandText = "DELETE FROM aspnet_Membership WHERE UserId ='" + userId + "'"; 

     connection.Open(); 

     cmd.ExecuteNonQuery(); 
     cmd1.ExecuteNonQuery(); 


     connection.Close(); 


     Response.Redirect("Home.aspx"); 
    } 

Thứ hai, là có cách nào tôi có thể thiết lập một hạn sử dụng đến URL? Nếu URL đang được nhấp lần thứ hai, URL sẽ không chuyển hướng người dùng đến bất kỳ địa điểm nào. Tôi thấy nhiều bài viết, hầu hết trong số họ khuyên bạn nên thêm một cột vào cơ sở dữ liệu. Có cách nào khác để tôi có thể đặt hết hạn mà không cần chạm vào cơ sở dữ liệu không ???

+0

bạn có tạo vai trò trong ứng dụng của mình không? –

+0

hi, tôi không tạo bất kỳ vai trò nào trong cấu hình .Net. – user1529419

Trả lời

5

Xem xét một trang riêng biệt cho liên kết thay đổi từ khóa. Yêu cầu trang này nhận dạng duy nhất. Số nhận dạng này chỉ hoạt động một lần, có ngày hết hạn và dành riêng cho người dùng đó. Đặt trang này công khai:

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

Bạn cần lưu trữ số nhận dạng duy nhất ở đâu đó với người dùng. Nếu bạn không muốn ảnh hưởng đến giản đồ hiện tại của mình, bạn có thể tạo bảng mới:

PK | Identifier | UserID        | expires 
1 | abcd  | ffffffff-ffff-ffff-ffff-ffffffffffff | 16-jul-2012 18:26 

Khi trang được yêu cầu, nếu số nhận dạng hết hạn không cho phép trang hoạt động. Khi mật khẩu đã được thay đổi, hãy vô hiệu hóa số nhận dạng - xóa nó hoặc đặt ngày hết hạn cho một cái gì đó trong quá khứ (ví dụ: ngay bây giờ).

+0

Xin chào, cảm ơn bạn đã trả lời. Từ bài đăng của Chris bên dưới - "Tại sao không xác thực họ và sau đó gửi họ đến trang hồ sơ?" Đây là những gì tôi hiện đang sử dụng .. Khi người dùng nhấp vào URL, hệ thống sẽ tự động xác thực người dùng, đó là lý do họ có thể tiếp tục vào UserProfile.aspx (không có vấn đề về quy tắc truy cập). Nhưng làm cách nào tôi có thể cho phép người dùng tự động đăng nhập bằng điều khiển đăng nhập asp.net? – user1529419

+0

@ user1529419. Miễn là bạn đang sử dụng UserID để xác định người dùng, bạn cũng có thể cho phép bất kỳ ai thay đổi mật khẩu của bất kỳ ai (như được Chris nói "đó không phải là điều tuyệt vời"). Tôi đề xuất bạn duy trì xác thực trên trang UserProfile.aspx của bạn. Nó có một mục đích khác nhau để "thay đổi mật khẩu". –

1

bạn có thể thử cho phép người dùng ẩn danh vào trang hồ sơ người dùng của mình bằng cách thêm thông tin sau vào web.config của bạn bên trong thẻ <configuration>.

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

nếu tôi không sai thì điều kiện này sẽ cho phép bất kỳ ai truy cập trang? sửa tôi xin vui lòng –

+0

@waqar. Cần phải cho phép tất cả người dùng vì người dùng có thể truy cập qua liên kết email "đặt lại mật khẩu". Xem câu trả lời của tôi cho một cách tiếp cận an toàn hơn. –

+0

@flem câu trả lời của bạn là đúng bcz bạn cho phép tất cả người dùng cho changepasswordpage nhưng sam là cho phép tất cả người dùng cho UserProfilePage. –

2

Đây không phải là một câu trả lời trực tiếp cho câu hỏi hỏi nhưng một lời nhận xét tổng quát hơn về các công cụ khôi phục mật khẩu cơ cấu ...

Khi mã hóa chức năng này, tôi muốn làm một vài điều khác nhau.

Truy cập trang hồ sơ hoặc chỉ cần thay đổi mật khẩu?

Thứ nhất, nếu người dùng chỉ cần thay đổi mật khẩu của họ, họ không cần truy cập vào trang hồ sơ người dùng chỉ là trang thay đổi mật khẩu.Tôi sẽ đưa họ thẳng đến một "thay đổi mật khẩu" trang và làm cho điều này cụ thể cho các chức năng đặt lại pasword và do đó có nó nặc danh có sẵn mà không có vấn đề.

Tại sao không xác thực cho họ và sau đó gửi chúng vào trang cấu hình?

Các thay thế khác là thay vì lộn xộn xung quanh với truy cập nặc danh đến những thứ chỉ làm một tính năng tự động đăng nhập. Url đó sẽ dẫn đến trang đích sẽ tự động đăng nhập người dùng đã cho (sau cùng bạn có tất cả chi tiết người dùng). Sau đó, họ có thể được chuyển hướng đến trang hồ sơ và họ không còn vô danh vì vậy tất cả đều tốt.

Những vấn đề với văn bản đơn giản id người dùng

Bạn cần phải sử dụng một mã thông báo tốt hơn. Nếu ai đó có thể tìm thấy id người dùng của người dùng khác (có thể nó hiển thị trong url nếu bạn nhấp để xem hồ sơ công khai của người dùng) thì họ có thể thay đổi mật khẩu người đó. Đó không phải là mát mẻ như tôi chắc chắn bạn biết.

để tôi sử dụng gì thay cho id người dùng rõ?

Tokens Random

Hai phương pháp xung quanh này đang tạo thẻ ngẫu nhiên mà bạn lưu trữ trong cơ sở dữ liệu và sau đó xác minh họ khi tải trang. Điều này sau đó tất nhiên làm cho nó rất dễ dàng để vô hiệu hóa chúng bằng cách chỉ cần thay đổi một cái gì đó trong cơ sở dữ liệu khi bạn muốn làm mất hiệu lực chúng. Bạn có thể lưu trữ một mã thông báo ngẫu nhiên (có thể tôi sẽ tìm chuỗi mã hóa base64 dài khoảng 16 ký tự - 96 bit ngẫu nhiên) trong DB cùng với bất kỳ thông tin cần thiết nào (ví dụ: userid, ngày tạo (hoặc ngày hết hạn) , v.v.) Nếu bạn muốn nó là một trong những sử dụng, bạn chỉ có thể xóa các mã thông báo ra khỏi DB một khi nó đã được xác nhận một lần (hoặc đánh dấu một lĩnh vực để nói nó được sử dụng hoặc bất kỳ số lựa chọn thay thế khác).

Encrypted Tokens

Phương pháp an toàn hơn mà không liên quan đến chạm vào cơ sở dữ liệu là tạo ra một dấu hiệu được mã hóa mà bạn có thể vượt qua đối với người dùng. Mã thông báo này có thể chứa userID và thời gian mã thông báo được tạo (và bất kỳ thông tin nào khác mà bạn cảm thấy thích) và sẽ được đưa vào e-mail và bị lãng quên. Bởi vì nó được mã hóa dữ liệu chứ không phải là một dấu hiệu ngẫu nhiên trên postback hơn là việc chứng thực qua cơ sở dữ liệu bạn chỉ có thể giải mã token cung cấp cho fidn người sử dụng và bao nhiêu tuổi token là.

Nếu bạn muốn sử dụng chúng mà không cần nhấn vào cơ sở dữ liệu, bạn có thể sẽ lưu trữ các mã thông báo được tạo trong từ điển ứng dụng máy chủ và nếu không có mã thông báo hợp lệ và bạn xóa nó khỏi danh sách bạn đang lưu trữ khi nó được sử dụng. Bạn cũng thường xuyên xóa các thẻ cũ để đảm bảo rằng bạn không lưu trữ quá nhiều rác. Cách tiếp cận này cũng có nhược điểm là nếu ứng dụng được khởi động lại, bạn sẽ xóa danh sách các thẻ và do đó làm mất hiệu lực tất cả chúng. Đây chỉ là một vấn đề nếu bạn cần họ là một shot mặc dù. Cá nhân tôi muốn cho phép họ đặt lại mật khẩu của họ tất cả họ muốn trong bất kỳ khung thời gian bạn xác định thích hợp với một mã thông báo duy nhất. :)

Một cảnh báo về ID người dùng rõ trong kịch bản gốc

Tôi không thể nhấn mạnh đủ cách cẩn thận bạn cần phải chỉ đặt userid trong bản rõ trong url như thông tin duy nhất thông qua. Thời điểm ai đó phát hiện ra người dùng của người khácID tài khoản của họ bị xâm phạm hiệu quả. Họ chỉ cần đặt người đó vào userid và họ có thể thay đổi mật khẩu của họ.

Thậm chí nếu bạn không có bất kỳ nơi nào hiển thị UserID của người khác, bạn phải chắc chắn 100% rằng bạn sẽ không bao giờ trong tương lai thực tế là không thể đảm bảo.

Các vấn đề liên quan