【问题标题】:Custom Authentication using legacy user table in Asp.Net Core使用 Asp.Net Core 中的旧用户表进行自定义身份验证
【发布时间】:2018-01-23 13:58:45
【问题描述】:

我需要从现有的旧用户表中对用户进行身份验证,但如果可能的话,我想在身份和授权的肩膀上进行身份验证,以便我可以使用这些功能和属性。我们的大多数用户已经从一个更老的本机应用程序登录,我们希望将其转移到我们的 Asp.net Core Intranet Web 应用程序。我在 SO 和其他地方看到了一些关于这个问题的主题,但似乎没有一个适合我的特定需求。

我应该采取的最佳方法是什么?

【问题讨论】:

  • 你不需要使用身份:stackoverflow.com/questions/31511386/…
  • @CuongLe,在接受的答案示例中,_userService.GetByEmail 将是一个自定义用户服务,我将在其中查询我自己的数据库,对吧?
  • 是的,正是---

标签: asp.net asp.net-core asp.net-identity asp.net-authorization


【解决方案1】:

我们的大多数用户已经从更老的本地人那里登录 我们想要转移到我们的 Asp.net Core Intranet 的应用程序 网络应用程序。

您可以使用 OWIN cookie 身份验证中间件。中间件在 ASP.NET Core 中稍作改动。

仅供参考:Microsoft 正在转向基于策略的授权,而不是基于角色的授权。角色声明是为了向后兼容。如果您打算将 AuthorizeAttribute 与角色一起使用,您可能需要查看此 sampleusage

https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/

Login Action Method

在 Login 动作方法中,我们首先使用现有的身份验证机制进行身份验证。然后将用户信息和角色名传递给 SignManager 方法。

[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        bool result = // Validate user
        if (result)
        {
            var user = await _userRepository.GetUserByUserNameAsync(model.UserName);
            var roleNames = (await _roleRepository.GetRolesForUser(user.Id))
                 .Select(r => r.Name).ToList();
            await _signInManager.SignInAsync(user, roleNames);            
        }
        else
        {
            ModelState.AddModelError("", "Incorrect username or password.");
        }
    }
    return View("Login", model);
}

SigIn Manager

然后我们创建用户信息作为声明。

public class SignInManager
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public SignInManager(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task SignInAsync(User user, IList<string> roleNames)
    {
        var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Sid, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.GivenName, user.FirstName),
                new Claim(ClaimTypes.Surname, user.LastName)
            };

        foreach (string roleName in roleNames)
        {
            claims.Add(new Claim(ClaimTypes.Role, roleName));
        }

        var identity = new ClaimsIdentity(claims, "local", "name", "role");
        var principal = new ClaimsPrincipal(identity);

        await _httpContextAccessor.HttpContext.Authentication
             .SignInAsync(Constants.AuthenticationScheme, principal);
    }

    public async Task SignOutAsync()
    {
        await _httpContextAccessor.HttpContext.Authentication
            .SignOutAsync(Constants.AuthenticationScheme);
    }
}

Startup.cs

最后,我们在 Startup.cs 中添加 cookie 身份验证中间件。

public void Configure(IApplicationBuilder app, 
       IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...   
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        Events = new CookieAuthenticationEvents
        {
            OnRedirectToAccessDenied = context =>
            {
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return TaskCache.CompletedTask;
            }
        },
        AuthenticationScheme = Constants.AuthenticationScheme,
        LoginPath = new PathString("/Account/Login"),
        AccessDeniedPath = new PathString("/Common/AccessDenied"),
        AutomaticAuthenticate = true,
        AutomaticChallenge = true
    });
    ...
}

【讨论】:

    猜你喜欢
    • 2016-07-05
    • 2020-05-20
    • 2017-02-15
    • 2018-02-24
    • 1970-01-01
    • 2016-07-05
    • 2021-11-06
    相关资源
    最近更新 更多