2010-11-21 14 views
22

FormsAuthenticationを使用して何かを保存するにはどうすればよいですか?私はUserIdをURLで保存したくありません。ASP.NET MVC 3(認証を使用)

は例えば、今、私はこのコードを持っている:

//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クラス:

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

ProjectRepository:ProjectControllerと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(); 
} 

。 ..誰かが助言を与えるかもしれない、URを使わずにUserIDを保存する方法L?これを行う最善の方法は、IDを自動化に保存することです。私は

UPD私は許しを請う

...これを行うにはUser.Identityに任意のプロパティを見つけていないが、私はかみそりビューとMVC-3を使用していると言うことを忘れていました。 そのUserIdは文字列ではありません(User.Identity.Nameは文字列です)。これはGUIDか自分自身のオブジェクトである可能性があります...

答えて

38

保存ユーザーがログオン認証クッキー内をFormsAuthenticationチケットのUserDataプロパティでユーザーID:

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); 

は、あなたが戻って、グローバルでのPostAuthenticateRequest方法でそれを読むことができます。asax:この場合には、CustomPrincipalは(あなたが役割を使用していない場合、私はあなたがGenericPrincipalから派生する必要があると思うが)RolePrincipalから導出し、単にユーザーIDプロパティを追加し、コンストラクタをオーバーロードすることを

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; 
} 

注意。アプリでユーザーIDを必要な場所

さて、あなたはこれを行うことができます:

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

のことです。それはセントを作る...私は明後日それを試してみます。 – RAMe0

+0

UserDataにUserIdを保存する最初の部分は不完全なようです。誰かがそのコードを適切なクラスに説明またはラップできるので、そのコードがどこにあるのか確認できますか?ありがとう。 –

1

私は質問を正しく理解していますが、

URL(例えばhttp://localhost/controller/action?username=RAMe0)を通さず、現在のユーザーが誰であるか取得する方法に、あなたはThread.CurrentPrincipal.Identity.Nameを使用して見ることができますかHttpContext.Current.User 2間の微妙な違いがあります。しかしながら。詳細はhereをご覧ください。

+0

をうーん...私は 'Current'の' HttpContext' ...のメンバーと別のものを持っていません。私はページをリロードすれば、どこから 'Current'が来ますか?しかし、私は 'HttpContext'に' Current'を持っていません。( – RAMe0

+0

System.Web.dllへの参照があり、コードファイルの先頭に "using System.Web;"があることを確認してください。 – CRice

+0

はい私は持っています: – RAMe0

1

FormsAuthenticationを使用すると、User.Identity.Nameプロパティにユーザー名を格納できます。おそらくあなたが探しているものの簡単な例があります。

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

これはqueryStringパラメータを介してユーザ名を渡す必要はありません(あなたがすでに使用している同じSetAuthを使用)。

+0

私がやっていることはまさに...私はUserIDを保存し、おそらく他の情報を、SetAuthCookieを使用して保存したい... – RAMe0

+0

元の書き込みを使用私はあなたがFormsServiceであることを認識した後に書き直しましたが、本当に 'this.User.Identity.Name'を使用する2番目のブロックに焦点を当てたかったのです。 – Buildstarted

+0

いつも'User.Identity.Name'の詳細情報(データが不足している場合はjsonのようなものです)あなた自身の' IIdentity'オブジェクトを実装することもできます。基本的にすべてのユーザ情報を 'User.Identity'それは難しいあなたの質問から教えてください。 – Buildstarted

5

まず、インターフェイス経由ですべての権限呼び出しを行う必要はありません。この方法では、認証を使用するすべてのコードは、IIdentity GetCurrentUserIdentityため

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

Implemenationはあなたが好きな方法かもしれログインが行われ、またはIndentityが格納されているか、などをどのように心配する必要はありません、しかし、一般的にあなたが見るLoginUserクラスは、メンバーシップユーザーに関する取得された情報がある

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.... 

} 

コールに「HttpContext.Current.User.Identity」として見られています。これは一般にMembershipProviderを介して行われますが、もちろん他の方法で行うこともできます。

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

誰がまだメンバーシッププロバイダーを使いたいのかわかりません。それが出て以来ずっとごみ箱になっています。独自の認証を担当してください。 – PositiveGuy

+2

これはまさにこれが – CRice

関連する問題