2017-08-28 27 views
3

コントローラーを特定の役割のみに制限したいとします。具体的には、adminとしましょう。 adminロールを持つユーザーを設定した後、私は彼がIsInRoleAsyncメソッドを使用してその役割を果たしていることを検証できます(真を返します)。 [Authorize(Roles = "admin")]で属性を設定すると、まったく同じユーザーで404が取得されます。私はベアラトークンを使用しています(これは関係ないと思いますが、とにかくです)、ここでデバッグを試みました。ASP.NET Core Identity 2.0 Authorize filter

コントローラなし[Authorize]:リソースが返されます。 [Authorize]で[OK]

コントローラー:でも役割のセットを持つユーザーでログインした後、私が手に:私は[Authorize(Roles = "admin")]Authentication: Bearer [access token] [OK]

コントローラーを使用のみときに、リソースが返されます

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc(); 

    // Add framework services. 
    services.AddDbContext<ApplicationDbContext>(options => 
    { 
     options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); 
     options.UseOpenIddict(); 
    }); 
    services.AddIdentity<ApplicationUser, IdentityRole>() 
     .AddEntityFrameworkStores<ApplicationDbContext>() 
     .AddDefaultTokenProviders(); 

    services.AddOpenIddict(opt => 
    { 
     opt.AddEntityFrameworkCoreStores<ApplicationDbContext>(); 
     opt.AddMvcBinders(); 
     opt.EnableTokenEndpoint("/api/token"); 
     opt.AllowPasswordFlow(); 
     opt.DisableHttpsRequirement(); //for dev only! 
     opt.UseJsonWebTokens(); 
     opt.AddEphemeralSigningKey(); 
     opt.AllowRefreshTokenFlow(); 
     opt.SetAccessTokenLifetime(TimeSpan.FromMinutes(5)); 
    }); 

    services.AddAuthentication(options => 
    { 
     options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme; 
     options.DefaultAuthenticateScheme = OAuthValidationConstants.Schemes.Bearer; 
     options.DefaultSignInScheme = IdentityConstants.ExternalScheme; 
    }) 
     .AddJwtBearer(options => 
     { 
      options.Authority = "http://localhost:44337/"; 
      options.Audience = "resource_server"; 
      options.RequireHttpsMetadata = false; 
      options.TokenValidationParameters = new TokenValidationParameters 
      { 
       NameClaimType = OpenIdConnectConstants.Claims.Subject, 
       RoleClaimType = OpenIdConnectConstants.Claims.Role 
      };     
     }); 
    services.Configure<IdentityOptions>(options => 
    { 
     // Password settings 
     options.Password.RequireDigit = true; 
     options.Password.RequiredLength = 8; 
     options.Password.RequireNonAlphanumeric = false; 
     options.Password.RequireUppercase = true; 
     options.Password.RequireLowercase = false; 

     // Lockout settings 
     options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); 
     options.Lockout.MaxFailedAccessAttempts = 10; 
     // User settings 
     options.User.RequireUniqueEmail = true; 
     // Add application services. 
     options.ClaimsIdentity.UserNameClaimType= OpenIdConnectConstants.Claims.Name; 
     options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject; 
     options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role; 
    }); 

    services.AddSingleton(typeof(RoleManager<ApplicationUser>)); 
    // Add application services. 
    services.AddTransient<IEmailSender, AuthMessageSender>(); 
    services.AddTransient<ISmsSender, AuthMessageSender>(); 

答えて

3

デフォルトの認証、サインイン/サインアウト、チャレンジ/禁止のスキームとして自動的に設定されたIDはservices.AddIdentity()によって自動的に設定されるため、アクセス拒否ページ(デフォルトではAccount/AccessDenied)にリダイレクトしようとしますが、これはおそらくアプリケーションには存在しません。 JWTは、マッピング機能が無効になっていると主張してください、あなたの第二の問題を解決するには

services.AddAuthentication(options => 
{ 
    // ... 
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 
    options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme; 
}); 

:それはあなたの問題を修正かどうかを確認するために、デフォルトの挑戦/禁断のスキームをオーバーライドする

してみてください。そうでない場合、JWTハンドラはroleのクレームをすべてClaimTypes.Roleに "変換"します。これは、ClaimsPrincipal.IsInRole(...)RoleClaimType = OpenIdConnectConstants.Claims.Role)によって使用されるロールクレームとしてroleを使用するように設定したときは機能しません。

services.AddAuthentication(options => 
{ 
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; 
}) 
.AddJwtBearer(options => 
{ 
    // ... 
    options.SecurityTokenValidators.Clear(); 
    options.SecurityTokenValidators.Add(new JwtSecurityTokenHandler 
    { 
     // Disable the built-in JWT claims mapping feature. 
     InboundClaimTypeMap = new Dictionary<string, string>() 
    }); 
}); 
+0

これは404を説明して解決していますが、なぜユーザーには必要な役割があるので、コンテンツにアクセスできないのですか?今、私は403 –

+0

@ダニエルを取得します。あなたの2番目の問題の修正プログラムでアップデートされました。 – Pinpoint

+0

あなたが述べたように、私の問題は、自分のトークンに「ロール」がないということでした。ユーザーにそのロールが割り当てられていれば、アイデンティティは「AspNetUserRoles」をチェックすると考えました。あなたの答えをありがとう –

1

私は何が必要だと思う:404 [NOK]

私はここに私はいくつかの設定を欠けている場合は知らないが、私のConfigureServicesですロールではなく、主張をチェックすることです。追加AuthorizeAttributeのような請求項が要求するポリシーを設定し、その後

[Authorize(Policy = "AdminOnly")] 

そして:

services.AddAuthorization(options => 
{ 
    options.AddPolicy("AdminOnly", policy => 
         policy.RequireClaim(OpenIdConnectConstants.Claims.Role, "Admin")); 
}); 

あるいは、目的やより高度な検証をデバッグするために、あなたが持っている可能性があり:

services.AddAuthorization(options => 
{ 
    options.AddPolicy("AdminOnly", policy => 
         policy.RequireAssertion(ctx => 
    { 
     //do your checks 
     return true; 
    })); 
}); 
+0

[マイクロソフト社の文書](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles)でもそうは思われませんが必要。つまり、違うもののように聞こえる。 –

+0

ロールは幾分古い学校ですが、今はそれがすべての主張です。 –

+0

そのポリシーのものであっても、404 –

関連する問題