Net Core 2.0 API设置授权和身份验证 [英] Net Core 2.0 API setting up authorization and authentication

查看:69
本文介绍了Net Core 2.0 API设置授权和身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个.net核心应用程序,我已经从1.1升级到2.0. 我遇到的问题是正在研究如何设置身份验证和授权.

I have a .net core application that I have upgraded from 1.1 to 2.0. The problem I am having is working out how to set up both authentication and authorization.

当我尝试击中api端点时遇到此异常...

I am getting this exception when I am trying to hit an api endpoint...

2017-08-15 15:28:12.2191 | 13 | Microsoft.AspNetCore.Server.Kestrel | ERROR | 连接ID"0HL73T7CAJGBE",请求ID"0HL73T7CAJGBE:00000001": 应用程序引发了未处理的异常.不 指定了authenticationScheme,并且没有 找到DefaultChallengeScheme.

2017-08-15 15:28:12.2191|13|Microsoft.AspNetCore.Server.Kestrel|ERROR| Connection id "0HL73T7CAJGBE", Request id "0HL73T7CAJGBE:00000001": An unhandled exception was thrown by the application. No authenticationScheme was specified, and there was no DefaultChallengeScheme found.

我的控制器具有此属性...

My controller has this attribute on it...

[Authorize(Policy ="Viewer3AuthPolicy")]

[Authorize(Policy = "Viewer3AuthPolicy")]

我的startup.cs具有尝试设置所有内容的方法...

My startup.cs has this method to try and set everything up...

   public void ConfigureServices(IServiceCollection services)
    {
    SetCorsPolicy(services);

    services.AddMvc();

    services.AddAuthentication(o =>
    {
        o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    });

    SetAuthorisationPolicy(services);

    services.AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
        options.AddPolicy("Viewer3AuthPolicy",
            policy => policy.RequireClaim(Constants.AuthPolicyClaimsName, Constants.AuthPolicyClaimsValue));
    });
}

在我的Configuremethod中,我正在呼叫...

In my Configuremethod I am calling...

app.UseAuthentication();

app.UseAuthentication();

我认为我必须在订购中有误,或者在设置中拨打了错误的电话.

I am thinking that I must have some ordering wrong or am making the wrong calls in the setup.

有人有什么想法吗?

推荐答案

使用_userManager.AddClaimsAsync的解决方案.这是我在 ConfigureServices 下进行的更改的简化版本:

Solution with _userManager.AddClaimsAsync. Here is the simplified version of changes I made under ConfigureServices:

services.AddAuthorization(options => {       
    options.AddPolicy("CRM", policy => { policy.RequireClaim("department", "Sales", "Customer Service", "Marketing", "Advertising", "MIS"); });
});

AccountController构造函数:

AccountController constructor:

    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IEmailSender _emailSender;
    private readonly ILogger _logger;

    private readonly MyDB_Context _context;

    public AccountController(
        MyDB_Context context,
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        IEmailSender emailSender,
        ILogger<AccountController> logger)
    {
        _context = context;
        _userManager = userManager;
        _signInManager = signInManager;
        _emailSender = emailSender;
        _logger = logger;
    }

登录下: ( var vUser 是我自己的类,具有属性名称,部门,SingIn等 ...).下面的示例结合使用自定义用户表 mytable (从声明类型及其值中读取)和 AspNetUserClaims 表格(添加声明):

Under LogIn: (var vUser is my own class with properties Name, department, SingIn, etc...). The sample below uses combination of custom user table mytable (to read from claim types and their values) and AspNetUserClaims table (to add claims):

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid) {
        var vUser = _context.mytable.SingleOrDefault(m => m.Email.ToUpper() == model.Email.ToUpper());

        const string Issuer = "https://www.mycompany.com/";
        var user = _userManager.Users.Where(u => u.Email == model.Email).FirstOrDefault();

        ApplicationUser applicationUser = await _userManager.FindByNameAsync(user.UserName);
        IList<Claim> allClaims = await _userManager.GetClaimsAsync(applicationUser); // get all the user claims

        // Add claim if missing
        if (allClaims.Where(c => c.Type == "department" && c.Value == vUser.department).ToList().Count == 0) {
            await _userManager.AddClaimAsync(user, new Claim("department", vUser.department, ClaimValueTypes.String, Issuer));
        }
        // Remove all other claim values for "department" type
        var dept = allClaims.Where(c => c.Type == "department" && c.Value != vUser.department);
        foreach(var claim in dept) {
            await _userManager.RemoveClaimAsync(user, new Claim("department", claim.Value, ClaimValueTypes.String, Issuer));
        }

        vUser.SignIn = DateTime.Now; _context.Update(vUser); await _context.SaveChangesAsync();

        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(vUser.Name, model.Password, model.RememberMe, lockoutOnFailure: false);
        //var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded) {
            _logger.LogInformation("User logged in.");
            return RedirectToLocal(returnUrl);
        }
        if (result.RequiresTwoFactor) {
            return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
        }
        if (result.IsLockedOut) {
            _logger.LogWarning("User account locked out.");
            return RedirectToAction(nameof(Lockout));
        } else {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

这是我的控制器中的内容:

[Authorize(Policy = "CRM")]
public class CRMController : Controller

这篇关于Net Core 2.0 API设置授权和身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆