2010-11-21 46 views
22

Làm cách nào tôi có thể lưu nội dung nào đó bằng cách sử dụng FormsAuthentication? Tôi không muốn lưu trữ UserId thông qua URL.ASP.NET MVC 3 bằng cách sử dụng xác thực

Ví dụ, bây giờ tôi có mã này:

//UserController class: 
[HttpPost] 
public ActionResult LogOn(LogOnModel model, string returnUrl) 
{ 
if (ModelState.IsValid) 
{ 
    if (repository.ValidateUser(model.Login, model.Password)) 
    { 
    FormsAuthentication.SetAuthCookie(model.Login, model.RememberMe); 
    if (Url.IsLocalUrl(returnUrl)) 
    { 
     return Redirect(returnUrl); 
    } 
    else 
    { 
     return RedirectToAction("Project", "Index"); 
    } 
    } 
    else 
    { 
    ModelState.AddModelError("", "Incorrect name or password."); 
    } 
} 

return View(model); 
} 

ProjectController lớp:

public ViewResult Index() 
{ 
    return View(repository.GetUserProjects(
     this.ControllerContext.HttpContext.User.Identity.Name)); 
} 

ProjectRepository:

ProjectsContext context = new ProjectsContext(); 
UsersContext uCnt = new UsersContext(); 

public IEnumerable<Project> GetUserProjects(String username) 
{ 
    if (String.IsNullOrEmpty(username)) 
     throw new ArgumentNullException("username", "Login is empty"); 
    return this.uCnt.Users 
       .FirstOrDefault(u => u.Login == username) 
       .Projects 
       .ToList(); 
} 

ProjectController và ProjectRepository không trông giống như mã tốt. .. Có thể ai đó có thể tư vấn, cách lưu trữ UserID mà không cần sử dụng UR L? Cách tốt nhất để làm điều này là lưu ID trên autorisation, tôi nghĩ. Tôi không tìm thấy bất kỳ tài sản trong User.Identity để làm điều này ...

UPD

Tôi cầu xin sự tha thứ, nhưng tôi quên nói rằng tôi đang sử dụng MVC-3 với Razor view. Và UserId đó không phải là một chuỗi (User.Identity.Name là một chuỗi) nó có thể là GUID hoặc có thể là đối tượng của riêng tôi ...

Trả lời

38

Save the UserID trong tài sản UserData vé FormsAuthentication trong cookie uỷ quyền khi người dùng đăng trên:

string userData = userID.ToString(); 

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.Email, 
    DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), 
    createPersistentCookie, userData); 
string hashedTicket = FormsAuthentication.Encrypt(ticket); 

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashedTicket); 
HttpContext.Current.Response.Cookies.Add(cookie); 

Bạn có thể đọc nó trở lại trong các phương pháp PostAuthenticateRequest trong toàn cầu.tuyến Asax:

HttpCookie formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 

if (formsCookie != null) 
{ 
    FormsAuthenticationTicket auth = FormsAuthentication.Decrypt(formsCookie.Value); 

    Guid userID = new Guid(auth.UserData); 

    var principal = new CustomPrincipal(Roles.Provider.Name, new GenericIdentity(auth.Name), userID); 

    Context.User = Thread.CurrentPrincipal = principal; 
} 

Lưu ý rằng trong trường hợp này, CustomPrincipal xuất phát từ RolePrincipal (mặc dù nếu bạn không sử dụng Vai trò, tôi nghĩ rằng bạn cần phải xuất phát từ GenericPrincipal), và chỉ cần thêm thuộc tính UserID và làm quá tải các nhà xây dựng.

Bây giờ, bất cứ nơi nào bạn cần UserID trong ứng dụng của bạn, bạn có thể làm điều này:

if(HttpContext.Current.Request.IsAuthenticated) 
    Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID; 
+2

Thats làm cho xu ... Tôi sẽ thử nó ngày sau khi ngày mai. – RAMe0

+0

Phần đầu tiên bạn lưu UserId trong UserData có vẻ không đầy đủ. Ai đó có thể giải thích hoặc bọc mã đó trong lớp thích hợp để tôi có thể thấy mã đó sống ở đâu? Cảm ơn. –

1

Tôi không chắc tôi hiểu câu hỏi một cách chính xác nhưng nếu bạn đang giới thiệu một cách để truy xuất người dùng hiện tại là ai mà không truyền qua URL (ví dụ: http://localhost/controller/action?username=RAMe0) thì bạn có thể xem bằng cách sử dụng Thread.CurrentPrincipal.Identity.Name hoặc HttpContext.Current.User

Có sự khác biệt tinh tế giữa hai Tuy nhiên. Hãy xem here để biết thêm chi tiết.

+0

Hmm ... Tôi không có 'viên Current' trong' HttpContext' ... Và một điều: từ đâu sẽ đến 'Hiện tại' nếu tôi tải lại trang? Nhưng thép tôi không có 'hiện tại' trong' HttpContext': ( – RAMe0

+0

Hãy chắc chắn rằng bạn có một tham chiếu đến System.Web.dll và rằng đầu tập tin mã của bạn đã "sử dụng System.Web;" – CRice

+0

Vâng tôi có nó : ( – RAMe0

1

Sử dụng FormsAuthentication bạn có thể lưu tên người dùng trong thuộc tính User.Identity.Name. Đây là một ví dụ đơn giản về những gì bạn có thể đang tìm kiếm. (Sử dụng cùng một số SetAuth bạn đang sử dụng)

public ViewResult Index() { 
    return View(repository.GetUserProjects(this.User.Identity.Name)); 
} 

Điều này không yêu cầu bạn chuyển tên người dùng thông qua tham số QueryString.

+0

Thats chính xác những gì tôi đang làm ... Tôi muốn lưu trữ UserID và có thể leter som thông tin khác, sử dụng SetAuthCookie ... – RAMe0

+0

Bản gốc được sử dụng Tôi đã viết lại nó sau khi tôi nhận ra bạn là FormsService.Nhưng tôi muốn thực sự tập trung vào khối thứ hai sử dụng 'this.User.Identity.Name'. – Buildstarted

+0

Bạn luôn có thể lưu trữ thêm thông tin trong 'User.Identity.Name' (giống như một json nếu dữ liệu của bạn là ngắn) .Bạn cũng có thể thực hiện đối tượng' IIdentity' của riêng mình. Bạn có muốn lưu trữ cơ bản tất cả thông tin người dùng trong 'User.Identity' hay không Thật khó o kể từ câu hỏi của bạn. – Buildstarted

5

Tại sao trước tiên không thực hiện tất cả lệnh gọi ủy quyền của bạn qua giao diện. Bằng cách này, tất cả các mã của bạn trong đó sử dụng xác thực không cần phải được quan tâm về cách thức đăng nhập được thực hiện, hoặc làm thế nào các indentity được lưu trữ, vv

public interface IAuthorization 
{ 
    bool ValidateUser(LoginUser u, string password); 
    LoginUser GetCurrentUser(); 
    void LogIn(LoginUser user); 
    void LogOut(); 
    IIdentity GetCurrentUserIdentity(); 
} 

implemenation cho IIdentity GetCurrentUserIdentity có thể là bất kỳ cách nào bạn thích, nhưng thường được xem là lời gọi đến "HttpContext.Current.User.Identity"

public class Authorization : IAuthorization 
{ 
    /// <summary> 
    /// Get the IIdentity for the current logged in user 
    /// </summary> 
    /// <returns>IIdentity</returns> 
    public virtual IIdentity GetCurrentUserIdentity() 
    { 
     return HttpContext.Current.User.Identity; 
    } 

    /// <summary> 
    /// Log the user in 
    /// </summary> 
    /// <param name="user">User details</param> 
    public void LogIn(LoginUser user) 
    { 
     InvalidCredentialsOnNullUser(user); 
     FormsAuthentication.SetAuthCookie(user.Name, false); 
    } 

    /// <summary> 
    /// Log the user out 
    /// </summary> 
    public void LogOut() 
    { 
     FormsAuthentication.SignOut(); 
    } 

    private static void InvalidCredentialsOnNullUser(LoginUser user) 
    { 
     if (user == null) 
     { 
      throw new InvalidCredentialException("That user doesn't exist or is not valid."); 
     } 
    } 

    // other methods.... 

} 

Lớp người dùng đăng nhập bạn thấy là thông tin được truy xuất về người dùng thành viên. Điều này thường được thực hiện thông qua một MembershipProvider nhưng tất nhiên có thể được thực hiện theo những cách khác.

public class LoginUser 
{ 
    public string Name; 
    public Guid Key; 
    public string EmailAddress; 
    public bool IsApproved; 
    public bool IsLockedOut; 
    public DateTime CreationDate; 
    public DateTime? LastLoginDate; 
    public DateTime? LastPasswordChangedDate; 
} 
+4

Tôi không biết tại sao bất cứ ai vẫn muốn sử dụng nhà cung cấp thành viên, điều đó là và đã được thùng rác kể từ khi nó ra. Vai trò auth của riêng bạn. – PositiveGuy

+2

Đó là chính xác những gì đây là – CRice

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