我正在使用OWIN开发ASP.Net应用程序,目前我的索赔存在问题。我有两个级别的应用程序:基本和高级。某些功能仅适用于高级用户。所以我检查索赔,如果用户没有索赔advanced
,我返回403.但是在这里我找到了破坏这个系统的解决方法:
我正在尝试为这种情况找到一些很好的解决方案,但除了set 1 minute timeout
或always check AspNetUserClaims instead of cookie
等我没有任何想法,但它们在我的情况下不起作用,因为他可以激活一个这一分钟间隔内的生命周期特征,然后永远使用它。
但我想设置一些服务器端标志,如oops, this guy have just changed his cookies, check it from database
或其他东西,以降低数据库往返的常见API调用。
有没有标准的默认方式呢?或者我刚刚选择了错误的仪器?
答案 0 :(得分:0)
您需要根据索赔价值发送更新Cookie。
以下是更新申请价值的代码。
当用户禁用/启用高级模式时,请执行操作,然后更新用户claims
。
var isAdvanced= "1";
var identity = (ClaimsIdentity)User.Identity;
// check if claim exist or not.
var existingClaim = identity.FindFirst("IsAdvanced");
if (existingClaim != null)
identity.RemoveClaim(existingClaim);
// add/update claim value.
identity.AddClaim(new Claim("IsAdvanced", isAdvanced));
IOwinContext context = Request.GetOwinContext();
var authenticationContext = await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
if (authenticationContext != null)
{
authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(identity,authenticationContext.Properties);
}
只要您进行重定向,您就会获得更新的索赔值,因此您不需要进行数据库往返。
答案 1 :(得分:0)
不幸的是,我找到的唯一方法实际上是查询数据库本身,并检查用户是否有有效的凭据:
public bool HasRequiredClaims(string[] requiredClaims)
{
using (var context = new ApplicationDbContext())
{
int actualNumberOfClaims = context.Users
.SelectMany(x => x.Claims)
.Count(c => requiredClaims.Contains(c.ClaimValue)); // claim values are unique per user (in my case) so I don't have to filter on user
return actualNumberOfClaims == claimsValuesToSearch.Length;
}
}