基于ASP.NET MVC 5身份用户在实体上构建过滤器



我都有一个调查平台,所有分数的商店列表。

我需要向每个用户提供基于其位置区域(区域(的商店。

我在我的MVC项目中使用Microsoft身份,我只发现了两个侵犯:

1-为每个区域构建一个配置文件,因此我可以根据记录的用户配置文件名称-DBContext.Where(位置== ProfilEname(

过滤

2-将应用程序用户扩展到包括该区域,因此我可以使用dbcontext.where(location == user.Identity.getLocation(((

过滤过滤器

或任何其他选项?

我已经能够实现第二个选项:

存储模型:

public enum PTLocationDistrict
{
    [Display(Name = "Aveiro")]
    Aveiro = 1,
    [Display(Name = "Beja")]
    Beja = 2,
    [Display(Name = "Braga")]
    Braga = 3
}
[Table("Stores")]
public class Store
{
    [Key]
    public int Id { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public PTLocationDistrict District { get; set; }
}

身份应用程序:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim("PTLocationDistrict", this.PTLocationDistrict.ToString()));
        return userIdentity;
    }
    // Additional properties for the Application User
    public PTLocationDistrict? PTLocationDistrict { get; set; }
}

身份服务:

   public static PTLocationDistrict? GetPTLocationDistrict(this IIdentity identity)
    {
        Claim claim = ((ClaimsIdentity)identity).FindFirst("PTLocationDistrict");
        PTLocationDistrict value;
        if (claim == null)
        {
            return null;
        }
        else if (Enum.TryParse(claim.Value, out value))
        {
            return value;
        }
        else
        {
            return null;
        }
    }

仪表板报告计数服务:

public int GetCountToday(PTLocationDistrict? ptLocationDistrict)
{
    try
    {
        var today = DateTime.Today;
        IQueryable<SurveySession> surveySessions = _dbContext.SurveySessions.AsNoTracking().AsQueryable();
        if (ptLocationDistrict != null)
        {
            surveySessions = surveySessions.Where(ss => ss.Location.District == ptLocationDistrict.Value);
        }
        int count = surveySessions
                            .Where(p => p.DateCreated >= today)
                            .Count();
        return count;
    }
    catch (Exception error)
    {
        _logger.Error("[Error in SurveyService.GetCountToday" - Error: " + error + "]");
        return 0;
    }
}

控制器动作:

public virtual ActionResult Index()
{
    IndexViewModel model = new IndexViewModel();
    PTLocationDistrict? ptLocationDistrict = User.Identity.GetPTLocationDistrict();
    // Realizados Hoje
    model.SurveyCountToday = _surveyService.GetCountToday(ptLocationDistrict);
}

看来,该信息不用于身份(基于位置拒绝访问(。因此,如果您有一个'Person'表,则可以将位置存储在此处,身份模型之外,然后在位置字段上的JOIN中使用此表。

如果没有,我只需在该位置添加索赔。优点是您可以阅读索赔而无需从数据库查找字段。您可以使用User.Identity.GetLocation(),假设这是读取包含位置的主张的扩展名。

您可以使用字段位置扩展IdentityUser,并根据字段添加索赔。但是,您不必在AspNetUserClaims表中添加索赔,因为它不喜欢更改。在这种情况下

请注意,仅当用户重新注销并再次注销或将令牌过期时,索赔的值才会更新。

- 更新 -

您可以创建一个customClaimType,类似的内容:

public const string LocationClaimType = "https://schemas.mycompany.com/claims/location";

,只要可以唯一地识别主张,这并不重要。

关于Aspnetuserclaims表没有太多可讲述的。插入记录,其中索赔类型是您的自定义索赔类型,并为特定用户设置值。并自动将其添加到身份中。您还可以将索赔添加到使用代码的用户。

在您的控制器中:

var identity = (System.Security.Claims.ClaimsIdentity)User.Identity;
var res = identity.Claims.FirstOrDefault(c => c.ValueType == LocationClaimType)?.Value;

您可以使用像上面的代码扩展身份(使用GetLocation(。您可以为CompanyId做同样的事情。

在这两种情况下

最新更新