gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 21:16:03 30 4
gpt4 key购买 nike

我正在尝试创建自己的依赖于 FormsAuthentication 的身份验证机制。我基本上使用 OAuth 来允许用户在授权服务器中进行身份验证,一旦他们通过身份验证,我需要使用 FormsAuthentication 在整个 session 中对他们进行身份验证。所以无论如何,我创建了一个 HttpModule 和一个帮助器类来完成这项工作。不幸的是,事实并非如此。

发生的情况是,在 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;
}
}

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

最佳答案

好吧,我终于解决了。就这么简单:

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

我需要告诉模块不要终止当前响应(因此是 false),以便它将在即将到来的请求中保留 cookie。

关于asp.net - 加密和解密 FormsAuthenticationTicket 以验证用户身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15416091/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com