我都有一个调查平台,所有分数的商店列表。
我需要向每个用户提供基于其位置区域(区域(的商店。
我在我的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做同样的事情。
在这两种情况下