ASP.NET Core - MVC Authorization

这篇文章介绍 .Net Core 下 Mvc 自带的身份验证和授权的使用方法

 

1. 有一个基础的 Mvc 框架

2. 有个自定义的 User 模型, 需要继承 Microsoft.AspNetCore.Identity.IdentityUser

public class ApplicationUser : IdentityUser
{
}

3. 建立数据上下文并链接数据库,

这里的上下文需要继承 Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext<>

这里的 IdentityDbContext 也是从 DbContext 继承而来, 所以跟原来的一样

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

4. 修改 StartUp

在 ConfigureService 里注册数据库和身份验证

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();
}

5. 建立 Account 控制器 和 Login, Register 等视图

(这里需要注意的是, 一旦访问需要权限的页面, 会自动跳到登陆界面, 这里登陆界面默认就是 Account/Login, 并不知道在哪里可以修改)

另外, 建立 AccountController 的时候, 需要注入2个管理器

public class AccountController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;

    public AccountController(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager)
    {
        _userManager = userManager;
        _signInManager = signInManager;
    }
}

6. 利用以上2个管理器来实现登陆和注册

public async Task<IActionResult> Login(LoginViewModel model)
{if (ModelState.IsValid)
    {
        var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction(nameof(HomeController.Index), "Home");
            }
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }
    }
    return View(model);
}
public async Task<IActionResult> Register(RegisterViewModel model)
{if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await _userManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await _signInManager.SignInAsync(user, isPersistent: false);

            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction(nameof(HomeController.Index), "Home");
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }
    return View(model);
}

 

public async Task<IActionResult> Logout()
{
    await _signInManager.SignOutAsync();
    return RedirectToAction(nameof(HomeController.Index), "Home");
}

 

 

 

 

 

还有一种轻量级自定义的验证方式

[HttpGet]
[AllowAnonymous]
public IActionResult SignIn()
{
    var output = new LoginInput();
    return View(output);
}

/// <summary>
///  登录
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> SignIn(LoginInput input)
{
    var context = new ExPlatDbContext();
    var user = context.User.SingleOrDefault(d => d.Name == input.Username);
    if (user == null || user.Password != input.Password || user.Role != 0)
    {
        input.Password = "";
        ModelState.AddModelError("", "用户名或密码错误");
        return View(input);
    }

    var claimIdentity = new ClaimsIdentity("Cookie");
    claimIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
    claimIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
    var claimsPrincipal = new ClaimsPrincipal(claimIdentity);
    await HttpContext.SignInAsync(claimsPrincipal);
    return RedirectToAction("Index", "Home");
}

/// <summary>
///  登出
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> SignOut()
{
    await HttpContext.SignOutAsync();
    return Ok(Success());
}

 

在 BaseController 里

public static UserInfo CurrentUser
{
    get
    {
        var user = System.Web.HttpContext.Current.User;
        // 取上下文中的用户信息
        return (user as CurrentUserCookie)?.CurrentUser;
    }
}

 

Starup 里面

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.LoginPath = "/main/user/signin";
});
 app.UseAuthentication();

 

posted @ 2017-11-16 16:28  `Laimic  阅读(511)  评论(0)    收藏  举报