Asp. Net авторизация ядра со статусом токена на предъявителя. Не авторизован 401 с токеном. - PullRequest
0 голосов
/ 01 мая 2020
    public class User: IdentityUser
    {
        // ... code here
    }


    [HttpPost]
    [Route("Login")]
    //POST: /api/User/Login
    public async Task<IActionResult> Login(LoginModel model)
    {
        var user = await _UserManager.FindByEmailAsync(model.Email);
        if (user != null && await _UserManager.CheckPasswordAsync(user, model.Password))
        {
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(
                    new Claim[]
                    {
                      new Claim("UserID", user.Id.ToString())
                    }),
                Expires = DateTime.UtcNow.AddDays(5),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_ApplicationSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
            };
            var tokenHandler = new JwtSecurityTokenHandler();
            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(securityToken);
            return Ok(new { token });
        }
        else
        {
            return BadRequest(new { message = "Username or password is incorrect" });
        }
    }

}

    [HttpGet]
    [Authorize]
    //GET: /api/UserProfile
    public async Task<Object> GetUserProfile()
    {
        var t = User.Claims.Count();

        string userId = User.Claims.First(c => c.Type == "UserID").Value;
        var user = await _UserManager.FindByIdAsync(userId);
        return new
        {
            user.FirstName,
            user.LastName,
            user.Email,
            user.ProfileType
        };
    }
}

Когда я пытаюсь получить подключенного пользователя с возвращенным токеном (используя почтальона), я всегда получаю статус 401 Unathorized. Кроме того, я обнаружил, что User.Claims.Count () равен 0 (я сделал это, комментируя, чтобы увидеть, что не так [Authorize]).

Кто-нибудь знает, в чем проблема?

Спасибо!

РЕДАКТИРОВАТЬ: Настройка приложения

    public void ConfigureServices(IServiceCollection services)
    {
        //Inject AppSettings
        services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));

        services.AddControllers();
        services.AddDbContext<AuthentificationContext>(
           options =>
           {
               options.UseMySql(Configuration.GetConnectionString("IdentityConnection"));
           });

        services.AddDefaultIdentity<User>()
                .AddEntityFrameworkStores<AuthentificationContext>();

        services.Configure<IdentityOptions>(options =>
        {
            options.Password.RequireDigit = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequiredLength = 6;
            options.User.RequireUniqueEmail = true;
        }
        );

        services.AddCors();

        //jwt authentification
        var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
        services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(x =>
       {
           x.RequireHttpsMetadata = false;
           x.SaveToken = false;
           x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
           {
               ValidateIssuerSigningKey = true,
               IssuerSigningKey = new SymmetricSecurityKey(key),
               ValidateIssuer = false,
               ValidateAudience = false,
               ClockSkew = TimeSpan.Zero
           };
       });

        services.Configure<CookiePolicyOptions>(options =>
        {
            services.AddHttpContextAccessor();
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.Use(async (ctx, next) =>
        {
            await next();
            if (ctx.Response.StatusCode == 204)
            {
                ctx.Response.ContentLength = 0;
            }
        });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(options =>
            options.WithOrigins(Configuration["ApplicationSettings:Client_URL"].ToString())
                   .AllowAnyMethod()
                   .AllowAnyHeader());

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        app.UseAuthentication();
    }
}

1 Ответ

0 голосов
/ 01 мая 2020

Следует обратить внимание на порядок промежуточного программного обеспечения, который ставит app.UseAuthentication(); перед app.UseAuthorization();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
...