Chr*_*ain 6 .net authorization azure-mobile-services
我有一个.NET Azure移动服务项目,其中包含一些我想用典型的Authorize属性保护的控制器.我可以创建一个Roles表和一个UserProfiles表,并将通过Google,Facebook等进行身份验证的各种用户与我的角色表中的角色相关联.
我的问题是:在身份验证完成之后但在授权过滤器的OnAuthorize方法运行之前,如何将Roles声明添加到ServiceUsers?这甚至可能吗?
我想做的例子:
[Authorize(Roles = "admin")]
public async Task<IHttpActionResult> Put(int id, MyDto dto){...}
Run Code Online (Sandbox Code Playgroud)
粗表示例:
Roles
id | name
1 | user
2 | admin
UserProfiles
id | externalLoginId | favoriteColor
1 | Google:<ServiceUser.Id> | blue
UserRoles (Linking Table)
roleId | userId
2 | 1
Run Code Online (Sandbox Code Playgroud)
编辑:
一个选项可能是创建我自己的操作过滤器覆盖Authorize过滤器属性,在OnAuthorize方法中我可以查询UserProfiles和Roles表以获取当前用户的角色,然后检查Authorize对象的Roles属性中指定的角色确定用户是否有权访问.但不知何故,感觉管道中应该有一个地方可以拦截,只是将Roles声明添加到当前用户.
我找到了解决方案。它涉及:
创建我自己的 ServiceTokenHandler 并重写 CreateServiceUser 方法以在调用 base.CreateServiceUser(claimsIdentity) 之后添加逻辑,该逻辑尝试在我的 UserProfile 表中查找链接到在 ClaimsIdentity 中指定的用户的角色。如果它找到角色,则会将新的角色声明添加到 ClaimsIdentity 的 Claims 集合中。
public class RolesServiceTokenHandler : ServiceTokenHandler
{
public RolesServiceTokenHandler(HttpConfiguration config) : base(config)
{
}
public override ServiceUser CreateServiceUser(ClaimsIdentity claimsIdentity)
{
var serviceUser = base.CreateServiceUser(claimsIdentity);
if (serviceUser != null && serviceUser.Identity.IsAuthenticated)
{
var dataContext = new AllergenDerivativesContext();
var userId = serviceUser.Id;
var userProfile = dataContext.UserProfiles.Include(u => u.Roles).FirstOrDefault(u => u.ExternalUserId == userId);
if (userProfile == null)
{
//If the user profile does not exist, then create it and assign it to the User role by default.
userProfile = new UserProfile();
//Set the ExternalUserId for the UserProfile to the current User's External Login Id.
userProfile.ExternalUserId = userId;
//Get the "User" Role Entity.
var userRole = dataContext.Roles.FirstOrDefault(r => r.Name == Roles.User);
//Initialize the roles collection for the new UserProfile
//And add the existing role to the collection.
userProfile.Roles = new List<Role> { userRole };
//Add the new UserProfile to the database and save the changes.
dataContext.UserProfiles.Add(userProfile);
dataContext.SaveChanges();
}
//Get the roles for the UserProfile and add role claims to the ServiceUser's primary Identity.
foreach (var role in userProfile.Roles)
{
((ClaimsIdentity)serviceUser.Identity).AddClaim(new Claim(ClaimTypes.Role, role.Name));
}
}
return serviceUser;
}
}
Run Code Online (Sandbox Code Playgroud)使用 autofac 将新的 RolesServiceTokenHandler 注册为 IServiceTokenHandler,以便当应用程序请求 IServiceTokenHandler 时,autofac 返回新的 RolesServiceTokenHandler。
在 WebApiConfig.cs 文件的静态 Register 方法中,更改对 ServiceConfig.Initialize 的调用,使其如下所示:
HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options, (httpConfig, autofac) =>
{
autofac.RegisterType<RolesServiceTokenHandler>().As<IServiceTokenHandler>();
}));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
651 次 |
| 最近记录: |