.net - 向 Azure 移动服务用户(Google、Twitter、Facebook、Microsoft)添加自定义角色

标签 .net authorization azure-mobile-services

我有一个 .NET Azure 移动服务项目,其中包含一些我想使用典型 Authorize 属性保护的 Controller 。我可以创建一个 Roles 表和一个 UserProfiles 表,并将通过 Google、Facebook 等进行身份验证的各种用户与我的 Roles 表中的角色相关联。

我的问题是:如何在身份验证完成后但在授权过滤器的 OnAuthorize 方法运行之前将 Roles 声明添加到 ServiceUsers?这甚至可能吗?

我想要做的例子:

[Authorize(Roles = "admin")]
public async Task<IHttpActionResult> Put(int id, MyDto dto){...}

粗表示例:
Roles
id | name
1  | user
2  | admin

UserProfiles
id | externalLoginId         | favoriteColor
1  | Google:<ServiceUser.Id> | blue

UserRoles (Linking Table)
roleId | userId
2      | 1

编辑:

一种选择可能是创建我自己的操作过滤器来覆盖授权过滤器属性,在 OnAuthorize 方法中,我可以查询 UserProfiles 和 Roles 表以获取当前用户的角色,然后检查 Authorize 对象的 Roles 属性中指定的角色以确定用户是否有权访问。但不知何故,感觉应该在管道中更早的地方有一个我可以拦截的地方,只需将 Roles 声明添加到当前用户。

最佳答案

我找到了解决方案。它涉及:

  • 创建我自己的 ServiceTokenHandler 并覆盖 CreateServiceUser 方法以在调用 base.CreateServiceUser(claimsIdentity) 后添加逻辑,该逻辑试图在我的 UserProfile 表中找到链接到在 claimIdentity 中指定的用户的角色。如果它找到角色,它会将新的角色声明添加到 claimIdentity 的 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;
        }
    }
    
  • 使用 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>();
                }));
    

    关于.net - 向 Azure 移动服务用户(Google、Twitter、Facebook、Microsoft)添加自定义角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30290710/

    相关文章:

    mysql - 如何改变 Node js 中的授权(权限)级别

    Azure 移动应用程序 - 离线数据同步 - 应用程序未运行

    .net - .NET 4 是否有内置的 JSON 序列化器/反序列化器?

    c# - 解释 NetCore 上 C# TcpClient/TcpListener 的奇怪行为

    C# 和 Zip 文件操作

    .net - 通过升级 .NET Framework 提高性能

    php - paypal returnurl 是登录页面

    authorization - XACML 将 PIP 结合到策略中

    使用 Azure 通知中心的 Android 推送通知

    c# - 解码 Azure 移动服务 JWT token 时出现 JwtSecurityToken 异常