首页 > 解决方案 > Angular 和 ASP.NET Core 角色基础问题

问题描述

我正在开发一个带有 ASP.NET Core 后端的 Angular Web 应用程序。我的角色有问题。成功登录后,我收到一个包含用户角色的令牌,但是当我尝试调用方法时,我总是从 asp.net 得到这个答案:http://localhost:5000/Account/Login?ReturnUrl=%2Fapi %2FClient%2F 详细信息。为什么?令牌有效且未过期。

角度:

getAllWithContactDetails(): Observable<ClientContact[]> {
  console.log(`here: ${localStorage.getItem('token')}`);
  return this.http.get<ClientContact[]>(`${links.API_URI}/api/Client/details`, {
    headers: new HttpHeaders({
      'Accept': 'application/json',
      'Authorization': `Bearer ${localStorage.getItem('token')}`
    })
  });
}

ASP.NET 核心

//Controller:
[HttpGet("details"), Authorize(Roles = "Admin,Employee,Seller")]
public IEnumerable<ClientContact> GetClientsWithContactDetails()
{
    ...
}

//Login:
...

var tokeOptions = new JwtSecurityToken(
    issuer: jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
    audience: jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
    claims: new List<Claim>() {
        new Claim(ClaimTypes.NameIdentifier, user.Id),
        new Claim(ClaimTypes.Name, user.UserName),
        new Claim(ClaimTypes.Role, _userManager.GetRolesAsync(user).Result.First())
    },
    expires: DateTime.Now.AddMinutes(10),
    signingCredentials: new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256)
);

return Ok(new { Token = new JwtSecurityTokenHandler().WriteToken(tokeOptions) });

ConfigureServicesStartup.cs

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                builder =>
                {
                    builder.WithOrigins("http://localhost:4200")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
        });

        services.AddDbContext<WebApiContext>(opt =>
           opt.UseSqlServer(Configuration.GetConnectionString("SlkDatabase")));

        var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

                ValidateAudience = true,
                ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

                ValidateIssuerSigningKey = true,
                IssuerSigningKey = _signingKey,

                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };
        });

        services.AddIdentity<User, IdentityRole>(options =>
            {
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireDigit = false;
                options.Password.RequireUppercase = false;
            })
            .AddEntityFrameworkStores<WebApiContext>()
            .AddDefaultTokenProviders();

        services.AddControllers();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi", Version = "v1" });
        });

        services.AddMvc().AddControllersAsServices();
    }

回复:

在此处输入图像描述

标签: angularasp.net-coreroles

解决方案


因此,我设法使用您的配置在新项目中重现了该问题。在这样做的同时,我记得我之前遇到了完全相同的问题。

问题是你AddAuthentication()先打电话,然后AddIdentity().

解决方案

ConfigureServices()中,您必须先调用AddIdentity(),然后AddAuthentication()使用自定义身份验证选项。

原因

在后台发生的事情是AddIdentity()扩展方法正在调用一堆其他扩展方法来添加身份认为必要的服务,以及它认为必要的配置。其中一部分是AddAuthentication()使用自己的身份验证选项进行调用。

因此,如果您在调用后调用它,它只会覆盖您的身份验证选项AddAuthentication()。这会导致可怕的重定向行为(顺便说一句,它做了正确的 302 重定向,我检查了它)。


让我知道这是否解决了这个问题。如果您在使用基于角色的授权时遇到其他问题,也请告诉我,因为我怀疑您会遇到。(编辑:我也测试了角色授权,实际上它对我有用。)


推荐阅读