1. 程式人生 > >Asp .Net Core 2.0 登錄授權以及多用戶登錄

Asp .Net Core 2.0 登錄授權以及多用戶登錄

environ rect != dir ipp 特性 toa 配置 cee

用戶登錄是一個非常常見的應用場景 .net core 2.0 的登錄方式發生了點變化,應該是屬於是良性的變化,變得更方便,更容易擴展。

配置

打開項目中的Startup.cs文件,找到ConfigureServices方法,我們通常在這個方法裏面做依賴註入的相關配置。添加如下代碼:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o 
=> { o.LoginPath = new PathString("/Account/Login"); o.AccessDeniedPath = new PathString("/Error/Forbidden"); }); }

這段代碼的大概意思就是,添加授權支持,並添加使用Cookie的方式,配置登錄頁面和沒有權限時的跳轉頁面。

再找到Configure方法,添加 app.UseAuthentication(),使用授權:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseAuthentication();
}

這樣基本的配置就完成了。

登錄

添加一個Controller,如AccountController,再添加一個Action,如 Login,所配置的路由,要與上面的配置對應,不然跳轉登錄時會跳錯頁面。

用戶提交用戶名和密碼,登錄代碼大致如下:

[HttpPost]
public async Task <IActionResult> Login(string userName, string password, string ReturnUrl)
{
    var user = _userService.Login(userName, password);
    if (user != null
) { user.AuthenticationType = CookieAuthenticationDefaults.AuthenticationScheme; var identity = new ClaimsIdentity(user); identity.AddClaim(new Claim(ClaimTypes.Name, user.UserID)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity)); if (ReturnUrl.IsNullOrEmpty()) { return RedirectToAction("Index", "Dashboard"); } return Redirect(ReturnUrl); } ViewBag.Errormessage = "登錄失敗,用戶名密碼不正確"; return View(); }

這裏要註意的是 AuthenticationType 所設置的Scheme一定要與前面的配置一樣,這樣對應的登錄授權才會生效。

使用登錄身份

登錄的目錄,就是希望有些頁面或者資源只有登錄以後才可訪問。使用AuthorizeAttribute來做限制。在需要做限制的Controller上加上[Authorize]特性來做限制。

[Authorize]
public class ThemeController
{
}

這樣這個Controller下的所有的Action都必需要登錄後才可訪問。如果希望其中某些Action可以不用登錄也可訪問,可以添加例外:

[AllowAnonymous]
public ActionResult Index()
{
    return View();
}

到這裏一個最基礎的登錄就完成了。

在Web項目中,通常會遇到一個問題,後端管理員和前臺用戶。這兩個用戶都是可登錄的,在 .net core 2.0,這個將很容易實現。

多用戶登錄

添加一個登錄方案(Scheme)

CookieAuthenticationDefaults.AuthenticationScheme,這是系統已經定義好的一個默認的登錄方案,添加一個新的來實現一個不同的身份登錄。代碼如下:

public class CustomerAuthorizeAttribute : AuthorizeAttribute
{
    public const string CustomerAuthenticationScheme = "CustomerAuthenticationScheme";
    public CustomerAuthorizeAttribute()
    {
        this.AuthenticationSchemes = CustomerAuthenticationScheme;
    }
}

添加使用這個新的方案,在Startup.cs文件下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>
            {
                o.LoginPath = new PathString("/Account/Login");
                o.AccessDeniedPath = new PathString("/Error/Forbidden");
            })
            .AddCookie(CustomerAuthorizeAttribute.CustomerAuthenticationScheme, option =>
            {
                option.LoginPath = new PathString("/Account/Signin");
                option.AccessDeniedPath = new PathString("/Error/Forbidden");
            });
}

添加新的登錄方案,並配置一個新的登錄頁面,登錄的方法和剛才是一樣,只是AuthenticationType使用了新的方案。

[HttpPost]
public async Task <IActionResult> Login(string userName, string password, string ReturnUrl)
{
    var user = _userService.Login(userName, password);
    if (user != null)
    {

        user.AuthenticationType = CustomerAuthorizeAttribute.CustomerAuthenticationScheme;
        var identity = new ClaimsIdentity(user);
        identity.AddClaim(new Claim(ClaimTypes.Name, user.UserID));
        await HttpContext.SignInAsync(CustomerAuthorizeAttribute.CustomerAuthenticationScheme, new ClaimsPrincipal(identity));

        if (ReturnUrl.IsNullOrEmpty())
        {
            return RedirectToAction("Index", "Dashboard");
        }
        return Redirect(ReturnUrl);
    }
    ViewBag.Errormessage = "登錄失敗,用戶名密碼不正確";
    return View();
}

驗證登錄狀態

使用方法和之前的差不多,換成新的CustomerAuthorizeAttribute就行了:

[CustomerAuthorize]
public class CustomerController
{
}

CustomerAuthorizeAttribute這個類,不是必需的,只是為了方便使用而寫,其實完全可以只定義一個新的方案(Scheme)就行了。

誰才是HttpContext.User?

登錄了多個用戶,那麽誰才是HttpContext.User呢?如果你的Controller或者Action上有使用AuthorizeAttribute,那這個Attribute使用的登錄方案是哪個,則這個HttpContext.User對應的就是那個方案的登錄用戶。如果沒有使用,則AddAuthentication()方法默認指它的方案(Scheme)所登錄的用戶,就是這個HttpContext.User了。

技術分享圖片

如何獲取對應方案的登錄用戶呢?使用HttpContext.AuthenticateAsync

var auth = await HttpContext.AuthenticateAsync(CustomerAuthorizeAttribute.CustomerAuthenticationScheme);
if (auth.Succeeded)
{
    auth.Principal.Identity...
}

退出登錄

這個就簡單了,指定方案退出就可以了。

public async Task Logout(string returnurl)
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    return Redirect(returnurl ?? "~/");
}

原文地址:http://www.zkea.net/codesnippet/detail/post-60

Asp .Net Core 2.0 登錄授權以及多用戶登錄