首页 > 代码库 > 如何在ASP.NET Core中实现一个基础的身份认证

如何在ASP.NET Core中实现一个基础的身份认证

注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core

如何在ASP.NET Core中实现一个基础的身份认证

ASP.NET终于可以跨平台了,但是不是我们常用的ASP.NET, 而是叫一个ASP.NET Core的新平台,他可以跨Windows, Linux, OS X等平台来部署你的web应用程序,你可以理解为,这个框架就是ASP.NET的下一个版本,相对于传统ASP.NET程序,它还是有一些不同的地方的,比如很多类库在这两个平台之间是不通用的。

 

今天首先我们在ASP.NET Core中来实现一个基础的身份认证,既登陆功能。

 

前期准备:

1.推荐使用 VS 2015 Update3 作为你的IDE,下载地址:www.visualstudio.com

2.你需要安装.NET Core的运行环境以及开发工具,这里提供VS版:www.microsoft.com/net/core

 

创建项目:

在VS中新建项目,项目类型选择ASP.NET Core Web Application (.NET Core), 输入项目名称为TestBasicAuthor。

技术分享

接下来选择 Web Application, 右侧身份认证选择:No Authentication

技术分享

 

打开Startup.cs

在ConfigureServices方法中加入如下代码:

services.AddAuthorization(); 

在Configure方法中加入如下代码:

app.UseCookieAuthentication(new CookieAuthenticationOptions {     AuthenticationScheme = "Cookie",     LoginPath = new PathString("/Account/Login"),     AccessDeniedPath = new PathString("/Account/Forbidden"),     AutomaticAuthenticate = true,     AutomaticChallenge = true }); 

完整的代码应该是这样:

public void ConfigureServices(IServiceCollection services) {     services.AddMvc();      services.AddAuthorization(); }  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {     app.UseCookieAuthentication(new CookieAuthenticationOptions     {         AuthenticationScheme = "Cookie",         LoginPath = new PathString("/Account/Login"),         AccessDeniedPath = new PathString("/Account/Forbidden"),         AutomaticAuthenticate = true,         AutomaticChallenge = true     });      app.UseMvc(routes =>     {         routes.MapRoute(              name: "default",              template: "{controller=Home}/{action=Index}/{id?}");     }); }

你或许会发现贴进去的代码是报错的,这是因为还没有引入对应的包,进入报错的这一行,点击灯泡,加载对应的包就可以了。

技术分享

在项目下创建一个文件夹命名为Model,并向里面添加一个类User.cs

代码应该是这样

public class User{    public string UserName { get; set; }    public string Password { get; set; }}

 

创建一个控制器,取名为:AccountController.cs

在类中贴入如下代码:

[HttpGet] public IActionResult Login() {     return View(); }  [HttpPost] public async Task<IActionResult> Login(User userFromFore) {     var userFromStorage = TestUserStorage.UserList         .FirstOrDefault(m => m.UserName == userFromFore.UserName && m.Password == userFromFore.Password);      if (userFromStorage != null)     {         //you can add all of ClaimTypes in this collection         var claims = new List<Claim>()         {             new Claim(ClaimTypes.Name,userFromStorage.UserName)             //,new Claim(ClaimTypes.Email,"emailaccount@microsoft.com")          };          //init the identity instances         var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "SuperSecureLogin"));          //signin         await HttpContext.Authentication.SignInAsync("Cookie", userPrincipal, new AuthenticationProperties         {             ExpiresUtc = DateTime.UtcNow.AddMinutes(20),             IsPersistent = false,             AllowRefresh = false         });          return RedirectToAction("Index", "Home");     }     else     {         ViewBag.ErrMsg = "UserName or Password is invalid";          return View();     } }  public async Task<IActionResult> Logout() {     await HttpContext.Authentication.SignOutAsync("Cookie");      return RedirectToAction("Index", "Home"); } 

相同的文件里让我们来添加一个模拟用户存储的类

//for simple, I‘m not using the database to store the user data, just using a static class to replace it.public static class TestUserStorage{    public static List<User> UserList { get; set; } = new List<User>() {        new User { UserName = "User1",Password = "112233"}    };}

接下来修复好各种引用错误。

完整的代码应该是这样

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;using TestBasicAuthor.Model;using System.Security.Claims;using Microsoft.AspNetCore.Http.Authentication;// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860namespace TestBasicAuthor.Controllers{    public class AccountController : Controller    {        [HttpGet]        public IActionResult Login()        {            return View();        }        [HttpPost]        public async Task<IActionResult> Login(User userFromFore)        {            var userFromStorage = TestUserStorage.UserList                .FirstOrDefault(m => m.UserName == userFromFore.UserName && m.Password == userFromFore.Password);            if (userFromStorage != null)            {                //you can add all of ClaimTypes in this collection                 var claims = new List<Claim>()                {                    new Claim(ClaimTypes.Name,userFromStorage.UserName)                     //,new Claim(ClaimTypes.Email,"emailaccount@microsoft.com")                  };                //init the identity instances                 var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "SuperSecureLogin"));                //signin                 await HttpContext.Authentication.SignInAsync("Cookie", userPrincipal, new AuthenticationProperties                {                    ExpiresUtc = DateTime.UtcNow.AddMinutes(20),                    IsPersistent = false,                    AllowRefresh = false                });                return RedirectToAction("Index", "Home");            }            else            {                ViewBag.ErrMsg = "UserName or Password is invalid";                return View();            }        }        public async Task<IActionResult> Logout()        {            await HttpContext.Authentication.SignOutAsync("Cookie");            return RedirectToAction("Index", "Home");        }    }    //for simple, I‘m not using the database to store the user data, just using a static class to replace it.    public static class TestUserStorage    {        public static List<User> UserList { get; set; } = new List<User>() {        new User { UserName = "User1",Password = "112233"}    };    }}

在Views文件夹中创建一个Account文件夹,在Account文件夹中创建一个名位index.cshtml的View文件。

贴入如下代码:

@model TestBasicAuthor.Model.User<html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title></head><body>    @using (Html.BeginForm())    {        <table>            <tr>                <td></td>                <td>@ViewBag.ErrMsg</td>            </tr>            <tr>                <td>UserName</td>                <td>@Html.TextBoxFor(m => m.UserName)</td>            </tr>            <tr>                <td>Password</td>                <td>@Html.PasswordFor(m => m.Password)</td>            </tr>            <tr>                <td></td>                <td><button>Login</button></td>            </tr>        </table>    }</body></html>

打开HomeController.cs

添加一个Action, AuthPage.

[Authorize][HttpGet]public IActionResult AuthPage(){    return View();}

在Views/Home下添加一个视图,名为AuthPage.cshtml

<html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title></head><body>    <h1>Auth page</h1>    <p>if you are not authorized, you can‘t visit this page.</p></body></html>

到此,一个基础的身份认证就完成了,核心登陆方法如下:

await HttpContext.Authentication.SignInAsync("Cookie", userPrincipal, new AuthenticationProperties{    ExpiresUtc = DateTime.UtcNow.AddMinutes(20),    IsPersistent = false,    AllowRefresh = false});

启用验证如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){    app.UseCookieAuthentication(new CookieAuthenticationOptions    {        AuthenticationScheme = "Cookie",        LoginPath = new PathString("/Account/Login"),        AccessDeniedPath = new PathString("/Account/Forbidden"),        AutomaticAuthenticate = true,        AutomaticChallenge = true    });}

在某个Controller或Action添加[Author],即可配置位需要登陆验证的页面。

 

最后:如何运行这个Sample以及下载完整的代码请访问:How to achieve a basic authorization in ASP.NET Core

如何在ASP.NET Core中实现一个基础的身份认证