asp.net - ASP.NET 加密和解密FormsAuthenticationTicket以验证用户身份

  显示原文与译文双语对照的内容

我正在尝试创建一个依赖 FormsAuthentication的我自己的认证机制。 我基本上使用OAuth允许用户在授权服务器上进行身份验证,一旦他们进行身份验证,我需要使用 FormsAuthentication 。 所以,我创建了一个 HttpModule 和一个 helper 类来做这个工作。 很 可惜 , 我们 无从 知晓 。

PostAuthenticateRequest 上,我加密票证并向响应添加 cookie,然后将用户重定向到网站的root 。 一旦用户被指定,另一个HTTP请求被发出,这样 HttpModule 就会被重新触发,以及我检查的AuthenticateRequest 事件。 为了检查用户是否已经过身份验证,我尝试读取 cookie,从它获取用户名并设置 Thread.CurrentPrincipal 属性。 但是,由于某种原因,饼干找不到。

这是我的代码:


public class OAuthModule : IHttpModule


{


 private const String USERNAME ="username";



 public void Dispose()


 {


 }



 public void Init(HttpApplication context)


 {


 context.AuthenticateRequest += context_AuthenticateRequest;


 context.PostAuthenticateRequest += context_PostAuthenticateRequest;


 }



 void context_PostAuthenticateRequest(object sender, EventArgs e)


 {


 var application = sender as HttpApplication;


 if (application!= null)


 {


 String username = application.Context.Items[USERNAME].ToString();


 String uri = RemoveQueryStringFromUri(application.Context.Request.Url.AbsoluteUri);


 var cookie = IdentityHelper.GetEncryptedFormsAuthenticationCookie(username, uri);


 application.Context.Response.Cookies.Add(cookie);



 application.Context.Response.Redirect(uri);


 }


 }



 void context_AuthenticateRequest(object sender, EventArgs e)


 {


 HttpApplication application = sender as HttpApplication;


 if (sender!= null)


 {


 if (!application.Context.Request.Url.AbsolutePath.Contains("."))


 {


 if (!IdentityHelper.IsAuthenticated)


 {


 HttpContextWrapper wrapper = new HttpContextWrapper(application.Context);


 String clientId = WebConfigurationManager.AppSettings["ClientId"];


 String clientSecret = WebConfigurationManager.AppSettings["ClientSecret"];


 String authorizationServerAddress = WebConfigurationManager.AppSettings["AuthorizationServerAddress"];


 var client = OAuthClientFactory.CreateWebServerClient(clientId, clientSecret, authorizationServerAddress);


 if (String.IsNullOrEmpty(application.Context.Request.QueryString["code"]))


 {


 InitAuthentication(wrapper, client);


 }


 else


 {


 OnAuthCallback(wrapper, client);


 }


 }


 }


 }


 }



 private void InitAuthentication(HttpContextWrapper context, WebServerClient client)


 {


 var state = new AuthorizationState();


 var uri = context.Request.Url.AbsoluteUri;


 uri = RemoveQueryStringFromUri(uri);


 state.Callback = new Uri(uri);


 var address ="https://localhost";


 state.Scope.Add(address);



 OutgoingWebResponse outgoingWebResponse = client.PrepareRequestUserAuthorization(state);


 outgoingWebResponse.Respond(context);


 }



 private void OnAuthCallback(HttpContextWrapper context, WebServerClient client)


 {


 try


 {


 IAuthorizationState authorizationState = client.ProcessUserAuthorization(context.Request);


 AccessToken accessToken = AccessTokenSerializer.Deserialize(authorizationState.AccessToken);


 String username = accessToken.User;


 context.Items[USERNAME] = username; 


 }


 catch (ProtocolException e)


 {


 EventLog.WriteEntry("OAuth Client", e.InnerException.Message);


 }


 }



 private String RemoveQueryStringFromUri(String uri)


 {


 int index = uri.IndexOf('?');


 if (index> -1)


 {


 uri = uri.Substring(0, index);


 }


 return uri;


 }


}



public class IdentityHelper


{


 public static Boolean IsAuthenticated


 {


 get


 {


 String username = DecryptFormsAuthenticationCookie();


 if (!String.IsNullOrEmpty(username))


 {


 SetIdentity(username);


 return Thread.CurrentPrincipal.Identity.IsAuthenticated;


 }


 return false;


 }


 }



 private static String DecryptFormsAuthenticationCookie() 


 {


 var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];


 if (cookie!= null)


 {


 FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);


 return ticket.UserData;


 }


 return String.Empty;


 }



 internal static HttpCookie GetEncryptedFormsAuthenticationCookie(String username, String domain)


 {


 var expires = DateTime.Now.AddMinutes(30);


 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, expires, true, username, FormsAuthentication.FormsCookiePath);


 var cookie = new HttpCookie(FormsAuthentication.FormsCookieName);


 cookie.Value = FormsAuthentication.Encrypt(ticket);


 cookie.Domain = domain;


 cookie.Expires = expires;


 return cookie;


 }



 private static void SetIdentity(String username)


 {


 ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim> { new Claim(ClaimTypes.Name, username) });


 var principal = new ClaimsPrincipal(claimsIdentity);


 Thread.CurrentPrincipal = principal;


 }


}



我 在 哪里 出 了错 ? 有什么想法吗?

时间: 原作者:

好的所以我终于解决了。 它和下面的一样简单:


application.Context.Response.Redirect(uri, false);



我需要告诉模块不要杀死当前响应( 因此 false ),以便在将来请求中保留 cookie 。

原作者:
...