r3p*_*ica 112 c# authentication asp.net-mvc claims-based-identity
我遇到了防伪令牌的问题:(我已经创建了自己的User类,但是现在每次进入/ Account/Register页面时我都会收到错误.错误是:
" http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier "或" http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider " 类型的声明是不在提供的ClaimsIdentity上.要使用基于声明的身份验证启用防伪令牌支持,请验证配置的声明提供程序是否在其生成的ClaimsIdentity实例上提供这两个声明.如果配置的声明提供程序使用不同的声明类型作为唯一标识符,则可以通过设置静态属性AntiForgeryConfig.UniqueClaimTypeIdentifier来配置它.
我找到了这篇文章:
所以我将Application_Start方法更改为:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,我收到了这个错误:
提供的ClaimsIdentity中没有" http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress " 类型的声明.
有没有人遇到过这个?如果是这样,你知道如何解决它吗?
提前干杯,
r3plica
更新1
这是我的自定义用户类:
public class Profile : User, IProfile
{
public Profile()
: base()
{
this.LastLoginDate = DateTime.UtcNow;
this.DateCreated = DateTime.UtcNow;
}
public Profile(string userName)
: base(userName)
{
this.CreatedBy = this.Id;
this.LastLoginDate = DateTime.UtcNow;
this.DateCreated = DateTime.UtcNow;
this.IsApproved = true;
}
[NotMapped]
public HttpPostedFileBase File { get; set; }
[Required]
public string CompanyId { get; set; }
[Required]
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public DateTime DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public DateTime LastLoginDate { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredTitle")]
public string Title { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredFirstName")]
public string Forename { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredLastName")]
public string Surname { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredEmail")]
public string Email { get; set; }
public string JobTitle { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public string Photo { get; set; }
public string LinkedIn { get; set; }
public string Twitter { get; set; }
public string Facebook { get; set; }
public string Google { get; set; }
public string Bio { get; set; }
public string CompanyName { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredCredentialId")]
public string CredentialId { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredSecurityCode")]
public bool IsLockedOut { get; set; }
public bool IsApproved { get; set; }
[Display(Name = "Can only edit own assets")]
public bool CanEditOwn { get; set; }
[Display(Name = "Can edit assets")]
public bool CanEdit { get; set; }
[Display(Name = "Can download assets")]
public bool CanDownload { get; set; }
[Display(Name = "Require approval to upload assets")]
public bool RequiresApproval { get; set; }
[Display(Name = "Can approve assets")]
public bool CanApprove { get; set; }
[Display(Name = "Can synchronise assets")]
public bool CanSync { get; set; }
public bool AgreedTerms { get; set; }
public bool Deleted { get; set; }
}
public class ProfileContext : IdentityStoreContext
{
public ProfileContext(DbContext db)
: base(db)
{
this.Users = new UserStore<Profile>(this.DbContext);
}
}
public class ProfileDbContext : IdentityDbContext<Profile, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
}
Run Code Online (Sandbox Code Playgroud)
我的配置文件对我的存储库来说很简单,看起来像这样:
public interface IProfile
{
string Id { get; set; }
string CompanyId { get; set; }
string UserName { get; set; }
string Email { get; set; }
string CredentialId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和用户类是Microsoft.AspNet.Identity.EntityFramework.User类.我的AccountController看起来像这样:
[Authorize]
public class AccountController : Controller
{
public IdentityStoreManager IdentityStore { get; private set; }
public IdentityAuthenticationManager AuthenticationManager { get; private set; }
public AccountController()
{
this.IdentityStore = new IdentityStoreManager(new ProfileContext(new ProfileDbContext()));
this.AuthenticationManager = new IdentityAuthenticationManager(this.IdentityStore);
}
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
return View();
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
try
{
// Create a profile, password, and link the local login before signing in the user
var companyId = Guid.NewGuid().ToString();
var user = new Profile(model.UserName)
{
CompanyId = companyId,
Title = model.Title,
Forename = model.Forename,
Surname = model.Surname,
Email = model.Email,
CompanyName = model.CompanyName,
CredentialId = model.CredentialId
};
if (await IdentityStore.CreateLocalUser(user, model.Password))
{
//Create our company
var company = new Skipstone.Web.Models.Company()
{
Id = companyId,
CreatedBy = user.Id,
ModifiedBy = user.Id,
Name = model.CompanyName
};
using (var service = new CompanyService())
{
service.Save(company);
}
await AuthenticationManager.SignIn(HttpContext, user.Id, isPersistent: false);
return RedirectToAction("Setup", new { id = companyId });
}
else
{
ModelState.AddModelError("", "Failed to register user name: " + model.UserName);
}
}
catch (IdentityException e)
{
ModelState.AddModelError("", e.Message);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// POST: /Account/Setup
public ActionResult Setup(string id)
{
var userId = User.Identity.GetUserId();
using (var service = new CompanyService())
{
var company = service.Get(id);
var profile = new Profile()
{
Id = userId,
CompanyId = id
};
service.Setup(profile);
return View(company);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它曾经使用[ValidateAntiForgeryToken]属性进行修饰,但这就是它停止工作的地方.
我希望这是足够的代码:)
Ale*_*ici 214
尝试设置(在global.cs中):
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
Run Code Online (Sandbox Code Playgroud)
Mik*_*win 58
你知道你在ClaimsIdentity中得到的主张吗?如果不:
[ValidateAntiForgeryToken]属性ClaimsIdentity并检查声明AntiForgeryConfig.UniqueClaimTypeIdentifier为该声明类型小智 24
把它放在global.asax.cs中
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;
Run Code Online (Sandbox Code Playgroud)
编辑:此刻对这个问题有了更深入的了解,您可以忽略我下面的回答。
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;Global.asax.cs 的 Application_Start() 中的设置为我解决了这个问题。尽管我已经http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier设置了声明,但我得到了与原始问题相同的错误。但如上所述指出它在某种程度上是有效的。
从 MVC4 开始,防伪令牌不再用作User.Identity.Name唯一标识符。相反,它会查找错误消息中给出的两个声明。
更新注意:这不是必需的 您可以在用户登录时将缺少的声明添加到您的 ClaimsIdentity 中,如下所示:
string userId = TODO;
var identity = System.Web.HttpContext.Current.User.Identity as ClaimsIdentity;
identity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", userId));
identity.AddClaim(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userId));
Run Code Online (Sandbox Code Playgroud)
请注意,其中一项声明可能之前就已存在,如果添加两者,您将收到重复声明的错误。如果是这样,只需添加缺少的一个即可。
小智 8
在 Global.asax.cs 中,
1.添加这些命名空间
using System.Web.Helpers;
using System.Security.Claims;
Run Code Online (Sandbox Code Playgroud)
2.在方法Application_Start中添加这一行:
protected void Application_Start()
{
.......
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63964 次 |
| 最近记录: |