に依存する独自の認証メカニズムを作成しようとしていますFormsAuthentication
。私は基本的に OAuth を使用して、ユーザーが認可サーバーで認証できるようにしています。認証されたらFormsAuthentication
、セッション全体で認証するために使用する必要があります。とにかく、これを機能さHttpModule
せるために と ヘルパー クラスを作成しました。残念ながら、そうではありません。
何が起こるかというとPostAuthenticateRequest
、チケットを暗号化し、応答に Cookie を追加してから、ユーザーを Web サイトのルートにリダイレクトします。ユーザーがリダイレクトされると、別の 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;
}
}
どこで私は間違えましたか?何か案は?