public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { bool isAnonymous = context.ActionDescriptor.HasAttribute <AllowAnonymousAttribute>(); if (isAnonymous) { return; } //TODO var userInfo = context.HttpContext.Session.Get <LoginUserContext>(LoginUserContext.InSessionKey); if (userInfo == null) { logger.Info("セッション内にユーザ情報がありません。ログイン画面に遷移します。"); //セッションにユーザ情報がなければログアウト状態にする。 await context.HttpContext.SignOutAsync(Startup.AuthScheme); //Ajaxの場合は401コードを返す(Javascript側でログインページにリダイレクト。) if (context.HttpContext.Request.IsApiOrAjaxRequest()) { context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized; string returnUrl = context.HttpContext.Request.Headers["Referer"].ToString(); //ログイン後に遷移するURL returnUrl = WebUtil.ToLocalUri(returnUrl); //ドメイン外のサイトに飛ばないよう、ローカルURL(http://ドメイン部分を除いたURL)に変換 string redirectUrl = $"{new PathString($"{IServiceCollectionExtentions.LoginPageUrl}")}?{IServiceCollectionExtentions.ReturnUrlParam}={returnUrl}"; context.HttpContext.Response.Headers.Add("redirectUrl", redirectUrl); context.Result = new EmptyResult(); } else { //context.Result = new RedirectResult(new PathString(IServiceCollectionExtentions.LoginPageUrl)); string originalUrl = context.HttpContext.Request.FullUrl(); string returnUrl = WebUtil.ToLocalUri(originalUrl); //ドメイン外のサイトに飛ばないよう、ローカルURL(http://ドメイン部分を除いたURL)に変換 // //Ajax以外の場合は通常のログイン画面へのリダイレクト処理。 var redirectUrl = $"{new PathString($"{IServiceCollectionExtentions.LoginPageUrl}")}?{IServiceCollectionExtentions.ReturnUrlParam}={returnUrl}"; context.Result = new RedirectResult(redirectUrl); } } }
/// <summary> /// 認証機能を設定する。 /// </summary> /// <param name="services"></param> public static void Authentication(this IServiceCollection services, IConfiguration Configuration) { //コンテキストパスがある場合はCookie名に付与する。(同じブラウザでみた場合に、クッキー値を上書きしあわないように。) var contextPathInfo = Configuration.GetContextPathInfo(); services.AddAuthentication(o => { o.DefaultScheme = Startup.AuthScheme; }) .AddCookie(options => { options.LoginPath = new PathString(LoginPageUrl); //ログインページ options.LogoutPath = new PathString("/view/Login/Logout"); //ログアウトページ options.AccessDeniedPath = new PathString("/view/Login/Deny"); //権限が無いページ表示時の処理 options.Cookie.Name = $".sample.Auth.{contextPathInfo.NoSlashContextPath}"; options.SlidingExpiration = true; //クッキーの有効期間 options.ExpireTimeSpan = AuthTimeoutSpan; //HttpOnlyなどは、Startup.Configure内で一律で設定している。 //options.Cookie.HttpOnly = false; //options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; //未認証時のリダイレクト処理を上書き options.Events.OnRedirectToLogin = (context) => { //Ajaxの場合は401コードを返す(Javascript側でログインページにリダイレクト。) if (context.Request.IsApiOrAjaxRequest()) { context.Response.Clear(); context.Response.StatusCode = StatusCodes.Status401Unauthorized; //ajaxのURLはPOSTなのでそのままリダイレクトすると404になる。 //Refererでajaxリクエストの送り元ページのURLを取得する。 string returnUrl = context.HttpContext.Request.Headers["Referer"].ToString(); //ログイン後に遷移するURL returnUrl = WebUtil.ToLocalUri(returnUrl); //ドメイン外のサイトに飛ばないよう、ローカルURL(http://ドメイン部分を除いたURL)に変換 string redirectUrl = $"{new PathString(LoginPageUrl)}?{ReturnUrlParam}={returnUrl}"; //?をPathStringのコンストラクタに渡すと%3Fに変換されてしまうので、外側で連結すること。 context.Response.Headers.Add("redirecturl", redirectUrl); //axiosでヘッダー名を取得すると全て小文字に変換される。ややこしいのでサーバー側も全て小文字にしておく。 return(Task.FromResult <object>(null)); } //string originalUrl = context.Request.FullUrl(); //Ajax以外の場合は通常のログイン画面へのリダイレクト処理。 //context.Response.Redirect(new PathString($"{LoginPageUrl}?{ReturnUrlParam}={originalUrl}")); context.Response.Redirect(context.RedirectUri); return(Task.FromResult <object>(null)); }; //権限が無い場合の処理 options.Events.OnRedirectToAccessDenied = (context) => { //Ajaxの場合は403コードを返す(Javascript側で権限ない旨のメッセージを表示。) if (context.Request.IsApiOrAjaxRequest()) { context.Response.Clear(); context.Response.StatusCode = StatusCodes.Status403Forbidden; return(Task.FromResult <object>(null)); } //Ajax以外の場合は通常のログイン画面へのリダイレクト処理。 context.Response.Redirect(context.RedirectUri); return(Task.FromResult <object>(null)); }; }); //偽造防止用設定 services.AddAntiforgery(opt => { opt.Cookie.Name = $".sample.Token.{contextPathInfo.NoSlashContextPath}"; //HttpOnlyなどは、Startup.Configure内で一律で設定している。 //opt.Cookie.HttpOnly = false; //opt.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; }); }