質問
私はUserクラスを持っており、ユーザーは、別のユーザーを偽装することができますMVCアプリを持っている(管理者ユーザーのみ)。
私は要求を認証し、Userクラスの私のバージョンをインスタンス化することを下回るこのコードを持っているので。
これは、その後、Sessionオブジェクトから偽装ユーザーを取得しようとしますが、セッションのglobal.asaxで、この方法では使用できません。
希望、これは理にかなっています。
私はこれを行うことができます他にどのように?
私の質問の私の推測では、Global.asaxのメソッドにどのような点にあるあなたが要求ごとにSessionオブジェクトへのアクセスを得るのですか?
protected void Application_OnAuthenticateRequest(object sender, EventArgs e)
{
IMylesterService service = ObjectFactory.GetInstance<IMylesterService>();
if (Context.User != null)
{
if (Context.User.Identity.IsAuthenticated)
{
User user = service.GetUser(Context.User.Identity.Name);
if (user == null)
throw new ApplicationException("Context.user.Identity.name is not a recognized user");
User impersonatedUser = (User)this.Session["ImpersonatedUser"];
if (impersonatedUser == null)
user.ImpersonatedUser = user;
else
user.ImpersonatedUser = impersonatedUser;
System.Threading.Thread.CurrentPrincipal = Context.User = user;
return;
}
}
User guest = service.GetGuestUser();
guest.ImpersonatedUser = guest;
System.Threading.Thread.CurrentPrincipal = Context.User = guest;
}
正しい解決策はありません
他のヒント
認証フィルタを作成してみてください
public class CustomAuthorizationFilter : AuthorizeAttribute
{
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
// perform your authorization here
// full access to HttpContext and session
}
}
次に、あなたのコントローラにこの属性を適用することができます。理想的には、他のすべてのコントローラが継承し、そのコントローラー上のクラスレベルで属性を適用することができるとベースのコントローラを持っていると思います。その後、すべてのあなたの要求を許可し、あなたが上にコード化されてきたように偽装を適用することになる。
セッションたAuthenticateRequest時に利用できません。何をする必要がありますすることはIdentity.userDataに、タグに必要な情報です。
:そう、たとえば、あなたはどこフォーム認証を使用すると、次の操作を行う場合void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.User != null)
{
if (Context.User.Identity.IsAuthenticated)
{
// retrieve the value
var id = (FormsIdentity)Context.User.Identity;
var myvalue = id.Ticket.UserData; // "Here you are"
}
}
}
フォームを使用してサインインするためには、カスタムクッキーを記述する必要があります。 MVC - >クラスFormsAuthenticationService:IFormsAuthenticationService
public static void SetAuthenticationCookie(HttpContextBase context, FormsAuthenticationTicket ticket)
{
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName)
{
Value = FormsAuthentication.Encrypt(ticket),
Secure = FormsAuthentication.RequireSSL,
Domain = FormsAuthentication.CookieDomain,
HttpOnly = true,
Expires = DateTime.Now.AddMinutes(15)
};
if (!context.Request.IsSecureConnection && FormsAuthentication.RequireSSL)
{
throw new HttpException("Ticket requires SSL.");
}
context.Response.Cookies.Add(cookie);
}
public static FormsAuthenticationTicket CreateTicket(HttpContextBase context, string emailAddress, string userData, bool persist)
{
return new FormsAuthenticationTicket(1, emailAddress, DateTime.Now, DateTime.Now.AddMinutes(15), persist, userData, FormsAuthentication.FormsCookiePath);
}
最後にサインインして、あなたが今CreateTicketを(...)を呼び出すことで、必要なチケットを作成し、その後、あなたはSetAuthenticationCookie(...)でそれを書くでしょう。
public void SignIn(string userName, string password)
{
if(CheckUserValid(userName,password, out string email))
{
var ticket = CreateTicket(email, "Here you are", true);
SetAuthenticationCookie(HttpContext.Current.Base(), ticket);
}
}
<時間>
私はそれを使用しませんが、セッション状態がしたAcquireRequestState時に割り当てられていることを前提としていたことがない。
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
}
私は、Global.asaxの中のアクセスセッションを必要とする、これと同じ問題を持っていたし、最終的に認証が渡された後に発生AcquireRequestState
ハンドラの中に私のコードを移動することによってそれを解決します。
protected void Application_AcquireRequestState(Object sender, EventArgs e)
{
if (Request.IsAuthenticated && Context.Session != null)
{
// access Context.Session
}
}
、これは多くのことを発射し、現在のコンテキストは常に有効なセッションオブジェクトを持っていませんので、チェックます。
編集:にisAuthenticatedがあまりにものチェックを追加する必要がありました - ログアウト時にヌル・エラーを得ていました。今偉大な作品ます。