介紹 本文章發佈於博客園:https://www.cnblogs.com/fallstar/p/11310749.html 作者:fallstar 本文章適用於:ASP.NET Core 2.1 + 今天想給一個asp.net core 的項目加上許可權驗證,於是研究了一下怎麼加, 折騰了好一陣,發現 ...
介紹
本文章發佈於博客園:https://www.cnblogs.com/fallstar/p/11310749.html
作者:fallstar
本文章適用於:ASP.NET Core 2.1 +
今天想給一個asp.net core 的項目加上許可權驗證,於是研究了一下怎麼加,
折騰了好一陣,發現原來Filter的方式被放棄了,現在使用Policy 和 Scheme 的方式來校驗了。。。
然後開始猛查 msdn 和 stackoverflow ,然而。。。找到的都不合適,我就要簡單容易的。。。
因為如果能直接用 AllowAnonymous和Authorize 可以省事好多的。
參照了 msdn ,有了第一版:
//Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x =>
{
x.LoginPath = new PathString("/Home/Login");//登錄頁面
x.LogoutPath = new PathString("/Home/Logout");//登出頁面
});
}
//HomeController .cs
/// <summary>
/// 首頁
/// </summary>
[Authorize]
public class HomeController : Controller
{
/// <summary>
/// 首頁
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View();
}
/// <summary>
/// 登錄
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public IActionResult Login()
{
return View();
}
/// <summary>
/// 登出
/// </summary>
/// <returns></returns>
public IActionResult Logout()
{
HttpContext.SignOutClain();
return RedirectToAction("Login");
}
}
上面的代碼很簡單,就用於授權跳轉,Index是首頁需要許可權,Login可以匿名訪問。
接著是用於提供拓展方法的WebHelper
直接在控制器的Action 裡面調用 HttpContext.Login 就可以了。
/// <summary>
/// Web幫助類
/// </summary>
public static class WebHelper
{
#region Auth
/// <summary>
/// 登錄
/// </summary>
public static bool Login(this HttpContext context, string username,string password)
{
//驗證登錄
if (!(username != "admin" && password != "123456"))
return false;
//成功就寫入
context.SignInClain(1, username, true, TimeSpan.FromHours(3));
return true;
}
/// <summary>
/// 將登錄用戶信息寫入憑據,輸出到cookie
/// </summary>
/// <param name="context"></param>
/// <param name="userid"></param>
/// <param name="username"></param>
/// <param name="isAdmin"></param>
public static async void SignInClain(this HttpContext context, int userid, string username, bool isAdmin = false, TimeSpan? expire = null)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.NameIdentifier,userid.ToString()),
new Claim(ClaimTypes.Role,isAdmin?"1":"0")
};
if (!expire.HasValue)
expire = TimeSpan.FromHours(3);
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties()
{
ExpiresUtc = DateTime.UtcNow.Add(expire.Value),
IsPersistent = true,
};
await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
}
/// <summary>
/// 登出,清除登錄信息
/// </summary>
/// <param name="context"></param>
public static async void SignOutClain(this HttpContext context)
{
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
#endregion
}
當我以為完事的時候。。。突然發現webapi也被帶到 登錄頁面去了。。。這肯定是不行的。
接著我有苦苦研究文檔,沒有收穫,最後,我仔細的查看配置項裡面的類,然後找到了辦法。
最終版就是下麵這段了:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Lax;
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x =>
{
x.LoginPath = new PathString("/Home/Login");//登錄頁面
x.LogoutPath = new PathString("/Home/Logout");//登出頁面
//多了下麵這段針對WebApi的代碼
x.Events.OnRedirectToLogin = z =>
{
if (z.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase))
{
z.HttpContext.Response.Redirect("/api/Login/UnAuth");//未授權錯誤信息的介面地址,返回json
}
else
{
z.HttpContext.Response.Redirect(z.RedirectUri);//其它安裝預設處理
}
return Task.CompletedTask;
};
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseCookiePolicy();
app.UseAuthentication();
//app.UseMvc
}
OK~大吉告成了~~~