c# - ASP.Net-Core 中的自定义身份验证

标签 c# asp.net authentication asp.net-core asp.net-core-mvc

我正在开发一个需要与现有用户数据库集成的网络应用程序。我仍然想使用 [Authorize] 属性,但我不想使用身份框架。如果我确实想使用身份框架,我会在 startup.cs 文件中添加如下内容:

services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
    options.Password.RequireNonLetterOrDigit = false;
}).AddEntityFrameworkStores<ApplicationDbContext>()
  .AddDefaultTokenProviders();

我假设我必须在那里添加其他东西,然后创建某种实现特定接口(interface)的类?有人能指出我正确的方向吗?我现在正在使用 asp.net 5 的 RC1。

最佳答案

经过几天的研究,我了解到, 这是 ASP .Net Core MVC 2.x 自定义用户身份验证指南

Startup.cs 中:

将以下行添加到 ConfigureServices 方法:

public void ConfigureServices(IServiceCollection services)
{

services.AddAuthentication(
    CookieAuthenticationDefaults.AuthenticationScheme
).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
    options =>
    {
        options.LoginPath = "/Account/Login";
        options.LogoutPath = "/Account/Logout";
    });

    services.AddMvc();

    // authentication 
    services.AddAuthentication(options =>
    {
       options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    });

    services.AddTransient(
        m => new UserManager(
            Configuration
                .GetValue<string>(
                    DEFAULT_CONNECTIONSTRING //this is a string constant
                )
            )
        );
     services.AddDistributedMemoryCache();
}

请记住,在上面的代码中我们说过,如果任何 未经身份验证 的用户请求一个带有 [Authorize] 注释的操作,他们将强制重定向到 /帐户/登录 url。

将以下行添加到Configure 方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler(ERROR_URL);
    }
     app.UseStaticFiles();
     app.UseAuthentication();
     app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: DEFAULT_ROUTING);
    });
}

创建您的 UserManager 类,该类也将管理登录和注销。它应该看起来像下面的代码片段(请注意我使用的是 dapper):

public class UserManager
{
    string _connectionString;

    public UserManager(string connectionString)
    {
        _connectionString = connectionString;
    }

    public async void SignIn(HttpContext httpContext, UserDbModel user, bool isPersistent = false)
    {
        using (var con = new SqlConnection(_connectionString))
        {
            var queryString = "sp_user_login";
            var dbUserData = con.Query<UserDbModel>(
                queryString,
                new
                {
                    UserEmail = user.UserEmail,
                    UserPassword = user.UserPassword,
                    UserCellphone = user.UserCellphone
                },
                commandType: CommandType.StoredProcedure
            ).FirstOrDefault();

            ClaimsIdentity identity = new ClaimsIdentity(this.GetUserClaims(dbUserData), CookieAuthenticationDefaults.AuthenticationScheme);
            ClaimsPrincipal principal = new ClaimsPrincipal(identity);

            await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
        }
    }

    public async void SignOut(HttpContext httpContext)
    {
        await httpContext.SignOutAsync();
    }

    private IEnumerable<Claim> GetUserClaims(UserDbModel user)
    {
        List<Claim> claims = new List<Claim>();

        claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id().ToString()));
        claims.Add(new Claim(ClaimTypes.Name, user.UserFirstName));
        claims.Add(new Claim(ClaimTypes.Email, user.UserEmail));
        claims.AddRange(this.GetUserRoleClaims(user));
        return claims;
    }

    private IEnumerable<Claim> GetUserRoleClaims(UserDbModel user)
    {
        List<Claim> claims = new List<Claim>();

        claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id().ToString()));
        claims.Add(new Claim(ClaimTypes.Role, user.UserPermissionType.ToString()));
        return claims;
    }
}

那么也许您有一个 AccountController,它有一个 Login 操作,应该如下所示:

public class AccountController : Controller
{
    UserManager _userManager;

    public AccountController(UserManager userManager)
    {
        _userManager = userManager;
    }

    [HttpPost]
    public IActionResult LogIn(LogInViewModel form)
    {
        if (!ModelState.IsValid)
            return View(form);
         try
        {
            //authenticate
            var user = new UserDbModel()
            {
                UserEmail = form.Email,
                UserCellphone = form.Cellphone,
                UserPassword = form.Password
            };
            _userManager.SignIn(this.HttpContext, user);
             return RedirectToAction("Search", "Home", null);
         }
         catch (Exception ex)
         {
            ModelState.AddModelError("summary", ex.Message);
            return View(form);
         }
    }
}

现在您可以在任何ActionController 上使用[Authorize] 注释。

如有任何问题或错误,请随时发表评论。

关于c# - ASP.Net-Core 中的自定义身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54808415/

相关文章:

c# - 使用 Enumerable.Empty<T>() 而不是 new List<T>() 来初始化 IEnumerable<T> 是否更好?

c# - List.Add vs HashSet.Add 用于 c# 中的小型集合

javascript - C# 相当于 Python 属性定制/Javascript 对象字面量

ASP.NET:如何从通用处理程序获取文件的虚拟路径?

asp.net - 你能运行一个 "service"来运行来自 ASP.Net 项目的计划任务吗?

asp.net - 从 DisplayFor 中删除 mailto anchor

php - Laravel JWT-auth 身份验证的注销问题

c# - C# 泛型类型的测试分配

Azure.Identity.CredentialUnavailableException问题

C#解锁工作站