web-dev-qa-db-ja.com

.netコアID 2.1の役割が機能しないことを許可する

2.1より前に、ロールベースの認証を数回実装しました。手順に従って、新しい2.1 IDを作成しました。

IdentityUserモデルを拡張してフィールドを追加し、ログインは正常に機能し、新しいフィールドが追加されました。

startup.cs構成サービスには

         services.AddDefaultIdentity<AppUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

役割をシードしました

         IdentityRole role = new IdentityRole();
         role.Name = "Administrator";
         IdentityResult roleResult = roleManager.
         CreateAsync(role).Result;

次に、ユーザーを作成し、ロールに追加しました

        AppUser user = new AppUser();
        user.UserName = "Admin";
        user.Email = "[email protected]";
        user.Name = "Administrator";
        user.LockoutEnabled = false;
        user.EmailConfirmed = true;

        IdentityResult result = userManager.CreateAsync(user, "password").Result;

        if (result.Succeeded)
        {
            userManager.AddToRoleAsync(user, "Administrator").Wait();
        }

すべて成功し、データベースは正常に見えます(AspNetUserRolesにはリンクがあります)

ただし、コントローラーをロールで装飾すると、常に未承認が返されます

       [Authorize(Roles = "Administrator")]

ただし、[Authorize](ロールなし)を使用した単純なログインチェックは機能します。

[Authorize]タグをステップスルー/デバッグできるように、これをどのように修正するか/ソースコードを組み込む最も簡単な方法は何ですか?

9
cdurth

直し方

ただし、コントローラーをロールで装飾すると、常に承認されていないが返されます

  [Authorize(Roles = "Administrator")]

これは2.1のバージョンの既知のバグです。 issue hereを参照してください。

私はアドバイスに従います HaoKとC-BERBERによって提案された古いapiを使用する で、今では問題なく動作しています。

これが私のDbContextです:

public class ApplicationDbContext : IdentityDbContext<AppUser,IdentityRole,string>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

古いスタイルのAPIを使用してIDを構成します。

services.AddIdentity<AppUser, IdentityRole>()
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddDefaultUI()
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();

最後に、logoutとre-signinがあり、期待どおりに動作します。

ソースコードをデバッグする方法

コンパイル時に処理されるので、AuthorizeAttribe自体をデバッグしたくないと思います。 AuthorizeFilterをデバッグする場合は、次の手順を実行できます。

Tools-> Options-> Debuggingをクリックします

  1. General内、unselectVisual StudioのEnable Just My Code
  2. Enable Source Link Supportを選択します
  3. Symbols内で、Microsoft Symbol Serversが選択されていることを確認してください

そして、ソースコードを今すぐデバッグできます。ただし、フィルターの動作方法により、MVCの前にブレークポイントを設定する必要があります。 MVCルーターハンドラーの前に行われるダミーのミドルウェアを設定しました。

enter image description here

デバッグAuthorizeFilerのスクリーンショット:

enter image description here

7
itminus

私のASP.NET Core 3(プレビュー)+ Angularの場合、ソリューションはAddAuthenticationにありました

services.AddDefaultIdentity<ApplicationUser>()
    .AddRoles<IdentityRole>()
    .AddRoleManager<RoleManager<IdentityRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
});
0
baur

クレームに役割を追加しました。次に、UI(HttpContext.User.IsInRole("Admin"))とauthorize属性([Authorize(Roles = "Admin")])の両方で機能します。

Startup.csファイル:

public void ConfigureServices(IServiceCollection services)
{    
    services.AddIdentity<ApplicationUser, IdentityRole>()                
      .AddEntityFrameworkStores<WandContext>();
    ///..... other code
} 

認証中に、クレームに役割を追加します。

var invalidLoginAttempt = false;
var user = await _userManager.FindByNameAsync(loginModel.Email);
if (user != null)
{
    var result = await _signInManager.CheckPasswordSignInAsync(user, loginModel.Password, lockoutOnFailure: true);

    if (result.Succeeded)
    {                                       
        var customClaims = new List<Claim>
        {
            new Claim(ClaimTypes.Role, Role.Admin)
        };

        var claimsIdentity = new ClaimsIdentity(customClaims, CookieAuthenticationDefaults.AuthenticationScheme);
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme,
            claimsPrincipal, new AuthenticationProperties { IsPersistent = loginModel.RememberMe });

        return LocalRedirect(returnUrl);
    }
    else if (result.IsLockedOut)
        ModelState.AddModelError(string.Empty, "This account has been locked out, please try again later.");
    else
        invalidLoginAttempt = true;
}
else
    invalidLoginAttempt = true;
0
Circuit Breaker