我有一个使用Identity 1.0的Asp.Net 5应用程序,我已经实现了一个自定义用户管理器,专门为用户角色提供自定义逻辑。
当我在控制器/操作上使用授权属性时,一切正常,但是当我在Razor页面上使用 User.IsInRole(roleName)时,自定义逻辑被忽略,返回的值不正确。
我已经针对此问题搜索了几个小时,但无法找到任何方法来覆盖 User.IsInRole(...)的默认行为。除非我遗漏了一些东西,否则我将不得不编写一个扩展方法,但在一些程序中实际使用自定义用户提供程序的实现似乎很荒谬!
编辑:自定义用户商店代码。我确信这是正确的,因为它与授权属性一起使用时正确执行,但是通过在方法上设置断点我可以确认在调用时它没有运行User.IsInRole(...)
public class CustomUserStore :
IUserStore<User, int>,
IUserLoginStore<User, int>,
IUserPasswordStore<User, int>,
IUserSecurityStampStore<User, int>,
IUserEmailStore<User, int>,
IUserLockoutStore<User, int>,
IUserTwoFactorStore<User, int>,
IUserPhoneNumberStore<User, int>,
IUserClaimStore<User, int>,
IUserRoleStore<User, int>,
IQueryableUserStore<User, int>,
IDisposable
{
// ...
public async Task<bool> IsInRoleAsync(User user, string roleName)
{
if (user == null)
throw new ArgumentNullException(nameof(user));
if (string.IsNullOrEmpty(roleName))
throw new ArgumentNullException(nameof(roleName));
using (SqlConnection con = new SqlConnection(connectionString))
{
// using Dapper.Net extension methods
var role = await con.QuerySingleOrDefaultAsync<Role>("select * from Roles where Name = @roleName", new { roleName });
if (role == null)
throw new InvalidOperationException($"Role {roleName} doesn't exist");
// calling this stored procedure directly on Sql Server yields expected results
var results = await con.QueryAsync("IsUserInRole", new { userId = user.Id, roleId = role.Id }, commandType: System.Data.CommandType.StoredProcedure);
return results.Count() > 0;
}
}
}
编辑2: 这是创建身份主体的代码:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: (user) => user.GetUserId<int>())
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
}
}