web-dev-qa-db-ja.com

ASP.NET Core Authorize属性がJWTで機能しない

ASP.Net CoreにJWTベースのセキュリティを実装したい。現時点では、Authorizationヘッダーのベアラートークンを読み取り、自分の条件に照らして検証するだけです。 ASP.Net Identityを含める必要はありません(必要ありません)。実際、私が本当に必要としない限り、MVCが追加するものを可能な限り使用しないようにしています。

問題を示す最小限のプロジェクトを作成しました。元のコードを見るには、編集履歴を見てください。このサンプルは、Authorization HTTPヘッダーに対応するベアラートークンを提供しない限り、/ api/iconsに対するすべてのリクエストを拒否することを期待していました。サンプル)は、実際にすべてのリクエストを許可します

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Routing;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System;
using Newtonsoft.Json.Serialization;

namespace JWTSecurity
{
    public class Startup
    {
        public IConfigurationRoot Configuration { get; set; }

        public Startup(IHostingEnvironment env)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(env.ContentRootPath);
            Configuration = builder.Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.AddAuthentication();
            services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("supersecretkey")),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                }
            });
            app.UseMvc(routes => routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"));
        }
    }
}

Controllers/IconsController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JWTSecurity.Controllers
{
    [Route("api/[controller]")]
    public class IconsController : Controller
    {
        [Authorize]
        public IActionResult Get()
        {
            return Ok("Some content");
        }
    }
}
20

それを見つけました!

主な問題は次の行にあります。

_services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
_

AddMvcCore()からAddMvc()に切り替えると、承認が突然機能し始めたことに気付きました! ASP.NETソースコード を掘り下げた後、AddMvc()の機能を確認するために、IMvcBuilder.AddAuthorization()への2回目の呼び出しが必要であることに気付きました。

_services.AddMvcCore()
    .AddAuthorization() // Note - this is on the IMvcBuilder, not the service collection
    .AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
_
48

ID認証も使用しており、暗黙的にCookie認証が含まれています。おそらく、IDスキームを使用してログインしたため、認証に成功しました。

ID認証が不要な場合は削除します(jwt認証のみが必要な場合)。そうでない場合は、以下のようにBearer属性にAuthorizeスキームを指定します。

[Authorize(ActiveAuthenticationSchemes = "Bearer")]
20
adem caglin

プレビューの回答を試しても問題を解決できなかった人のために、以下は私の場合の問題の解決方法です。

[Authorize(AuthenticationSchemes="Bearer")]
4
Andre Mendonca