在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。

huangapple go评论82阅读模式
英文:

The Authorize attribute in ASP.NET Core WebAPI controller with the Roles is not work

问题

I tried using [Authorize(Roles="role")] on my controller, but it doesn't work. Later, I checked using IsInRole to confirm if the role was successfully added, but it always shows false.

However, I found an article that had previously addressed this problem, so I tried the suggested solution, but it still didn't work.

我尝试在我的控制器上使用 [Authorize(Roles="role")],但它不起作用。后来,我使用 IsInRole 来确认角色是否成功添加,但它总是显示为false。

然而,我找到了一篇先前解决这个问题的文章,所以我尝试了建议的解决方案,但它仍然不起作用。

Link to the Stack Overflow article

我希望你帮我查找代码中的任何问题。

user.IsInRole("Developer") 返回 false,但 _userManager.IsInRoleAsync(user1, "Developer") 返回 true

var user = HttpContext.User;
var ss = user.IsInRole("Developer"); // 返回 false
var user1 = await _userManager.Users.FirstOrDefaultAsync(x => x.UserName == User.FindFirstValue(ClaimTypes.Name));
var sss = await _userManager.IsInRoleAsync(user1, "Developer");  // 返回 true

这是我的用户注册过程。

if (await _userManager.Users.AnyAsync(x => x.UserName == registerDto.Username))
{
   ModelState.AddModelError("username", "Username taken");
   return ValidationProblem();
}

var user = new AppUser
{
   DisplayName = registerDto.DisplayName,
   UserName = registerDto.Username
};
var role = registerDto.Role;

if (await _roleManager.RoleExistsAsync(role))
{
   var result = await _userManager.CreateAsync(user, registerDto.Password);

   if (result.Succeeded == false)
   {
       return BadRequest(result.Errors);
   }

   await _userManager.AddToRoleAsync(user, role);
   return await CreateUserObject(user);
}

return BadRequest($"Role {role} not found");

更新:
这是 AspNetRoles 表。
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。

更新2:
我的其他设置。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(opt =>
            {
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = key,
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
                opt.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) &&
                            HubPath.CheckStartsWithSegments(path))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });
builder.Services.AddControllers(opt =>
{
    var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
    opt.Filters.Add(new AuthorizeFilter(policy));
});
英文:

I tried using [Authorize(Roles="role")] on my controller, but it doesn't work. Later, I checked using IsInRole to confirm if the role was successfully added, but it always shows false.

However, I found an article that had previously addressed this problem, so I tried the suggested solution, but it still didn't work.

https://stackoverflow.com/questions/53271496/asp-net-core-identity-2-user-isinrole-always-returns-false

I would like you to help me identify any issues in my code.

user.IsInRole("Developer") is return false, but _userManager.IsInRoleAsync(user1, "Developer") is return ture.

var user = HttpContext.User;
var ss = user.IsInRole("Developer"); // return false
var user1 = await _userManager.Users
                .FirstOrDefaultAsync(x => x.UserName == User.FindFirstValue(ClaimTypes.Name));
var sss = await _userManager.IsInRoleAsync(user1, "Developer");  // return true
services.AddIdentityCore<AppUser>(opt =>
            {
                opt.Password.RequireDigit = false;
                opt.Password.RequiredLength = 0;
                opt.Password.RequireLowercase = false;
                opt.Password.RequireUppercase = false;
                opt.Password.RequireNonAlphanumeric = false;
                opt.User.RequireUniqueEmail = false;
            })
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<DataContext>();

services.AddScoped<IUserClaimsPrincipalFactory<AppUser>,UserClaimsPrincipalFactory<AppUser, IdentityRole>>();

Here is my user registration process.

if (await _userManager.Users.AnyAsync(x => x.UserName == registerDto.Username))
{
   ModelState.AddModelError("username", "Username taken");
   return ValidationProblem();
}

var user = new AppUser
{
   DisplayName = registerDto.DisplayName,
   UserName = registerDto.Username
};
var role = registerDto.Role;

if (await _roleManager.RoleExistsAsync(role))
{
   var result = await _userManager.CreateAsync(user, registerDto.Password);

   if (result.Succeeded == false)
   {
       return BadRequest(result.Errors);
   }

   await _userManager.AddToRoleAsync(user, role);
   return await CreateUserObject(user);
}

return BadRequest($"Role {role} not found");

Updete:
It's AspNetRoles table.
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。

Update 2:
My others setting.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(opt =>
            {
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = key,
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
                opt.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) &&
                            HubPath.CheckStartsWithSegments(path))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });
builder.Services.AddControllers(opt =>
{
    var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
    opt.Filters.Add(new AuthorizeFilter(policy));
});

答案1

得分: 1

以下是代码的中文翻译部分:

AspNetIdentityDbContext.cs

public class AspNetIdentityDbContext : IdentityDbContext<IdentityUser>
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseMySql("server=192.168.2.68;database=wa99UserAuth;user=mysql1;password=Q!q11111", new MySqlServerVersion(new Version()));
    }
}

program.cs

builder.Services.AddDbContext<AspNetIdentityDbContext>();
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<AspNetIdentityDbContext>();

controller

[ApiController]
public class ValuesController : ControllerBase
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;
    private readonly SignInManager<IdentityUser> _signInManager;

    public ValuesController(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, SignInManager<IdentityUser> signInManager)
    {
        this._userManager = userManager;
        this._roleManager = roleManager;
        this._signInManager = signInManager;
    }

    [HttpPost("AddRole")]
    public async Task<string> AddRole(string role)
    {
        var role2 = new IdentityRole { Name = role };         
        var result = await _roleManager.CreateAsync(role2);
        if (result.Succeeded)
        {
            return "成功";
        }
        else
        {
            return "错误";
        }
    }

    [HttpPost("register")]
    public async Task<string> register(string username, string password, string role)
    {
        var user = new IdentityUser
        {
            UserName = username
        };

        if (await _roleManager.RoleExistsAsync(role))
        {
            var result = await _userManager.CreateAsync(user, password);
            if (result.Succeeded)
            {
                await _userManager.AddToRoleAsync(user, role);
                return "成功";
            }
            else
            {
                return "错误";
            }
        }
        else
        {
            return "错误";
        }
    }

    [HttpPost("login")]
    public async Task<string> login(string username, string password)
    {
        var result = await _signInManager.PasswordSignInAsync(username, password, true, false);
        if (result.Succeeded)
        {
            return "成功";
        }
        else
        {
            return "错误";
        }
    }

    [Authorize(Roles = "Developer")]
    [HttpGet("test")]
    public async Task test()
    {
        var user = HttpContext.User;
        var ss = user.IsInRole("Developer"); 
        var user1 = await _userManager.Users.FirstOrDefaultAsync(x => x.UserName == "user1");
        var sss = await _userManager.IsInRoleAsync(user1, "Developer");  
    }
}

测试:

  1. 添加一个名为"Developer"的角色
  2. 注册一个用户"testUser",密码为"Q@q11111",角色为"Developer"
  3. 登录该用户
  4. 运行测试,ss为true
英文:

You can try the following code for a test.(.net6 api project)<br>
AspNetIdentityDbContext.cs

    public class AspNetIdentityDbContext : IdentityDbContext&lt;IdentityUser&gt;
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySql(&quot;server=192.168.2.68;database=wa99UserAuth;user=mysql1;password=Q!q11111&quot;, new MySqlServerVersion(new Version()));
}
}

program.cs

builder.Services.AddDbContext&lt;AspNetIdentityDbContext&gt;();
builder.Services.AddIdentity&lt;IdentityUser, IdentityRole&gt;()
.AddEntityFrameworkStores&lt;AspNetIdentityDbContext&gt;();

controller

    [ApiController]
public class ValuesController : ControllerBase
{
private readonly UserManager&lt;IdentityUser&gt; _userManager;
private readonly RoleManager&lt;IdentityRole&gt; _roleManager;
private readonly SignInManager&lt;IdentityUser&gt; _signInManager;
public ValuesController(UserManager&lt;IdentityUser&gt; userManager,RoleManager&lt;IdentityRole&gt; roleManager,SignInManager&lt;IdentityUser&gt; signInManager)
{
this._userManager = userManager;
this._roleManager = roleManager;
this._signInManager = signInManager;
}
[HttpPost(&quot;AddRole&quot;)]
public async Task&lt;string&gt; AddRole(string role)
{
var role2 = new IdentityRole { Name = role };         
var result = await _roleManager.CreateAsync(role2);
if (result.Succeeded)
{
return &quot;Succeed&quot;;
}
else
{
return &quot;Error&quot;;
}
}
[HttpPost(&quot;register&quot;)]
public async Task&lt;string&gt; register(string username,string password,string role)
{
var user = new IdentityUser
{
UserName = username
};
if (await _roleManager.RoleExistsAsync(role))
{
var result = await _userManager.CreateAsync(user, password);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, role);
return &quot;Succeed&quot;;
}
else
{
return &quot;Error&quot;;
}
}
else
{
return &quot;Error&quot;;
}
}
[HttpPost(&quot;login&quot;)]
public async Task&lt;string&gt; login(string username,string password)
{
var result = await _signInManager.PasswordSignInAsync(username, password, true, false);
if (result.Succeeded)
{
return &quot;Succeed&quot;;
}
else
{
return &quot;Error&quot;;
}
}
[Authorize(Roles = &quot;Developer&quot;)]
[HttpGet(&quot;test&quot;)]
public async Task test()
{
var user = HttpContext.User;
var ss = user.IsInRole(&quot;Developer&quot;); 
var user1 = await _userManager.Users.FirstOrDefaultAsync(x =&gt; x.UserName == &quot;user1&quot;);
var sss = await _userManager.IsInRoleAsync(user1, &quot;Developer&quot;);  
}
}

Test:<br>
1.Add a role name "Developer"<br>
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。<br>
2.Register a user "testUser" password "Q@q11111" with role "Developer"<br>
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。<br>
3.Signin the user<br>
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。<br>
4.Run test ,ss is true
在ASP.NET Core WebAPI控制器中,带有角色的Authorize属性不起作用。

huangapple
  • 本文由 发表于 2023年6月8日 15:13:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定