認証を使用した ASP.NET MVC 3
-
26-09-2019 - |
質問
FormsAuthentication を使用して何かを保存するにはどうすればよいですか?URL を介して UserId を保存したくありません。
たとえば、次のコードがあります。
//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
:
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 と ProjectRepository は良いコードとは思えません...URL を使用せずに UserID を保存する方法を誰かがアドバイスしてくれるかもしれません。これを行う最善の方法は、自動化時に ID を保存することだと思います。これを行うためのプロパティが User.Identity に見つかりませんでした...
更新
申し訳ありませんが、Razor ビューで MVC-3 を使用していることを忘れていました。そして、そのUserIdは文字列ではありません(User.Identity.Nameは文字列です)、GUIDまたはおそらく私自身のオブジェクトである可能性があります...
解決
保存の許可クッキーときにユーザーがログイン中を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);
あなたは戻っGlobal.asaxの中PostAuthenticateRequest方法でそれを読むことができます
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;
}
注RolePrincipalから、この場合、CustomPrincipalの派生する(あなたが役割を使用していない場合、私はあなたがGenericPrincipalから派生する必要があると思うが)、単にコンストラクタはユーザーIDプロパティやオーバーロードを追加します。
あなたのアプリでユーザーIDを必要な場所さて、あなたはこれを行うことができます:
if(HttpContext.Current.Request.IsAuthenticated)
Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;
他のヒント
なぜ最初のインタフェースを介してすべてのあなたの許可呼び出しを行いません。この方法では、すべての認証を使用してコードのログインが行われ、またはIndentityが格納されているか、などをどのように心配する必要はありません。
public interface IAuthorization
{
bool ValidateUser(LoginUser u, string password);
LoginUser GetCurrentUser();
void LogIn(LoginUser user);
void LogOut();
IIdentity GetCurrentUserIdentity();
}
IIdentity GetCurrentUserIdentityためImplemenationは、あなたが好きな方法かもしれないが、一般的に「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....
}
あなたが見るLoginUserクラスは、メンバーシップユーザーに関する取得された情報です。これは一般の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;
}
質問を正しく理解しているかどうかはわかりませんが、URL を介さずに現在のユーザーを取得する方法について言及しているのであれば (例: http://localhost/controller/action?username=RAMe0)その後、Thread.CurrentPrincipal.Identity.Name または HttpContext.Current.User を使用して確認できます。
ただし、この 2 つには微妙な違いがあります。見て ここ 詳細については。
あなたはFormsAuthentication
プロパティにユーザー名を格納することができUser.Identity.Name
を使用します。ここでは、おそらく探しているものの簡単な例です。 (すでに使用している同じSetAuth
を使用)
public ViewResult Index() {
return View(repository.GetUserProjects(this.User.Identity.Name));
}
このはqueryStringパラメータを介してユーザ名を渡す必要はありません。