Asp.net 加密和解密FormsAuthenticationTicket以验证用户身份
我正在尝试创建自己的身份验证机制,该机制依赖于Asp.net 加密和解密FormsAuthenticationTicket以验证用户身份,asp.net,asp.net-mvc,asp.net-mvc-4,forms-authentication,httpmodule,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Forms Authentication,Httpmodule,我正在尝试创建自己的身份验证机制,该机制依赖于FormsAuthentication。我基本上使用OAuth来允许用户在授权服务器中进行身份验证,一旦他们通过身份验证,我需要使用FormsAuthentication在整个会话中对他们进行身份验证。无论如何,我创建了一个HttpModule和一个helper类来实现这一点。不幸的是,事实并非如此 发生的情况是,在PostAuthenticateRequest上,我加密票据并向响应中添加cookie,然后将用户重定向到网站的根目录。重新定向用户后,
FormsAuthentication
。我基本上使用OAuth来允许用户在授权服务器中进行身份验证,一旦他们通过身份验证,我需要使用FormsAuthentication
在整个会话中对他们进行身份验证。无论如何,我创建了一个HttpModule
和一个helper类来实现这一点。不幸的是,事实并非如此
发生的情况是,在PostAuthenticateRequest
上,我加密票据并向响应中添加cookie,然后将用户重定向到网站的根目录。重新定向用户后,将发出另一个HTTP请求,以便再次触发HttpModule
,在AuthenticateRequest
事件中,我将检查此用户是否经过身份验证。为了检查用户是否经过身份验证,我尝试读取cookie,从中获取用户名,然后设置Thread.CurrentPrincipal
属性。但是,由于某些原因,无法找到cookie
这是我的密码:
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;
}
}
公共类OAuthModule:IHttpModule
{
私有常量字符串USERNAME=“USERNAME”;
公共空间处置()
{
}
公共void Init(HttpApplication上下文)
{
context.AuthenticateRequest+=context\u AuthenticateRequest;
context.PostAuthenticateRequest+=context\u PostAuthenticateRequest;
}
void context\u PostAuthenticateRequest(对象发送方,事件参数e)
{
var应用程序=发送方作为HttpApplication;
if(应用程序!=null)
{
字符串username=application.Context.Items[username].ToString();
字符串uri=RemoveQueryStringFromUri(application.Context.Request.Url.AbsoluteUri);
var cookie=IdentityHelper.GetEncryptedFormsAuthenticationCookie(用户名,uri);
application.Context.Response.Cookies.Add(cookie);
application.Context.Response.Redirect(uri);
}
}
void context_AuthenticateRequest(对象发送方,事件参数e)
{
HttpApplication application=发送方作为HttpApplication;
if(发送方!=null)
{
如果(!application.Context.Request.Url.AbsolutePath.Contains(“.”)包含
{
如果(!IdentityHelper.IsAuthenticated)
{
HttpContextWrapper=新的HttpContextWrapper(application.Context);
字符串clientId=WebConfigurationManager.AppSettings[“clientId”];
字符串clientSecret=WebConfiguration Manager.AppSettings[“clientSecret”];
String authorizationServerAddress=WebConfiguration Manager.AppSettings[“authorizationServerAddress”];
var client=OAuthClientFactory.CreateWebServerClient(clientId、clientSecret、authorizationServerAddress);
if(String.IsNullOrEmpty(application.Context.Request.QueryString[“code”]))
{
初始化身份验证(包装器、客户端);
}
其他的
{
OnAuthCallback(包装器、客户端);
}
}
}
}
}
私有void InitAuthentication(HttpContextWrapper上下文,WebServerClient客户端)
{
var state=新授权状态();
var uri=context.Request.Url.AbsoluteUri;
uri=RemoveQueryStringFromUri(uri);
state.Callback=新Uri(Uri);
变量地址=”https://localhost";
state.Scope.Add(地址);
OutgoingWebResponse OutgoingWebResponse=client.PrepareRequestUserAuthorization(状态);
outgoingWebResponse.Response(上下文);
}
AuthCallback上的私有void(HttpContextWrapper上下文,WebServerClient)
{
尝试
{
IAAuthorizationState authorizationState=client.ProcessUserAuthorization(context.Request);
AccessToken AccessToken=AccessTokenSerializer.Deserialize(authorizationState.AccessToken);
字符串username=accessToken.User;
context.Items[USERNAME]=用户名;
}
捕获(协议例外e)
{
WriteEntry(“OAuth客户端”,e.InnerException.Message);
}
}
私有字符串RemoveQueryStringFromUri(字符串uri)
{
int index=uri.IndexOf('?');
如果(索引>-1)
{
uri=uri.Substring(0,索引);
}
返回uri;
}
}
公共类标识帮助器
{
已验证公共静态布尔值
{
得到
{
字符串用户名=DecryptFormsAuthenticationCookie();
如果(!String.IsNullOrEmpty(用户名))
{
SetIdentity(用户名);
返回Thread.CurrentPrincipal.Identity.IsAuthenticated;
}
返回false;
}
}
私有静态字符串解密FormsAuthenticationCookie()
{
var cookie=HttpContext.Current.Request.Cookies[FormsAuthentication.FormScookeName];
if(cookie!=null)
{
FormsAuthenticationTicket票证=FormsAuthentication.Decrypt(cookie.Value);
返回票证.UserData;
}
返回字符串。空;
}
内部静态HttpCookie GetEncryptedFormsAuthenticationCookie(字符串用户名,字符串域)
{
var expires=DateTime.Now.AddMinutes(30);
FormsAuthenticationTicket票证=新的FormsAuthenticationTicket(1,用户名,日期时间。现在,过期,true,用户名,FormsAuthentication.FormsScookePath);
var cookie=新的HttpCookie(FormsAuthentication.formscookeName);
cookie.Value=FormsAuthentication.Encrypt(票据);
cookie.Domain=域;
cookie.Expires=过期;
返回cookie;
}
私有静态void SetIdentity(字符串用户名)
{
ClaimsIdentity ClaimsIdentity=新索赔
application.Context.Response.Redirect(uri, false);