Ich habe ein Problem mit dem Anti-Fälschungs-Token :( Ich habe meine eigene Benutzerklasse erstellt, die einwandfrei funktioniert hat. Jetzt wird jedoch eine Fehlermeldung angezeigt, wenn ich zur Seite / Account / Register gehe . Der Fehler lautet:
Ein Anspruch vom Typ " http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier " oder " http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider " lautete nicht auf der bereitgestellten ClaimsIdentity vorhanden. Stellen Sie sicher, dass der konfigurierte Anspruchsanbieter beide Ansprüche für die von ihm generierten ClaimsIdentity-Instanzen bereitstellt, um die Unterstützung von Fälschungssicherungs-Token mit anspruchsbasierter Authentifizierung zu aktivieren. Wenn der konfigurierte Anspruchsanbieter stattdessen einen anderen Anspruchstyp als eindeutige Kennung verwendet, kann dieser durch Festlegen der statischen Eigenschaft AntiForgeryConfig.UniqueClaimTypeIdentifier konfiguriert werden.
Ich habe diesen Artikel gefunden:
Also habe ich meine Application_Start- Methode folgendermaßen geändert :
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}
aber wenn ich das mache, bekomme ich diesen Fehler:
Ein Anspruch vom Typ ' http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress ' war auf der angegebenen ClaimsIdentity nicht vorhanden.
Hat jemand das schon einmal gesehen? Wenn ja, wissen Sie, wie Sie es lösen können?
Prost im Voraus,
r3plica
Update 1
Hier ist meine benutzerdefinierte Benutzerklasse:
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>
{
}
Mein Profil ist für meine Repositorys einfach und sieht folgendermaßen aus:
public interface IProfile
{
string Id { get; set; }
string CompanyId { get; set; }
string UserName { get; set; }
string Email { get; set; }
string CredentialId { get; set; }
}
und die Benutzerklasse ist die Microsoft.AspNet.Identity.EntityFramework.User- Klasse. Mein AccountController sieht folgendermaßen aus:
[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);
}
}
}
Früher war es mit dem Attribut [ValidateAntiForgeryToken] dekoriert , aber dort funktionierte es nicht mehr.
Ich hoffe das ist genug Code :)
Antworten:
Versuchen Sie die Einstellung (in global.cs):
quelle
AntiForgery
Klasse an, dieNameIdentifier
(die von gefundene Benutzer-ID-ZeichenfolgeGetUserId
) zu verwenden. Vielen Dank an Mike Goodwins Antwort, die mir dabei geholfen hat, dies zu lernen!Wissen Sie, welche Ansprüche Sie in Ihrer ClaimsIdentity erhalten? Wenn nicht:
[ValidateAntiForgeryToken]
AttributClaimsIdentity
und prüfen Sie die AnsprücheAntiForgeryConfig.UniqueClaimTypeIdentifier
Anspruchstyp ein[ValidateAntiForgeryToken]
Attribut zurückquelle
[ValidateAntiForgeryToken]
Attribut zurückFügen Sie dies einfach in global.asax.cs ein
quelle
Versuchen Sie, den Link im Inkognito-Fenster zu öffnen oder Cookies aus dieser Domain (dh localhost) zu löschen.
quelle
Bearbeiten: Wenn Sie dieses Problem in diesem Moment besser verstehen, können Sie meine Antwort unten ignorieren.
Die Einstellung
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
in Application_Start () von Global.asax.cs hat dies für mich behoben. Obwohl ich den Anspruchhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
festgelegt habe, erhalte ich den gleichen Fehler wie in der ursprünglichen Frage. Aber darauf hinzuweisen, wie oben, funktioniert irgendwie.Ab MVC4 wird das Anti-Fälschungs-Token nicht
User.Identity.Name
als eindeutige Kennung verwendet. Stattdessen wird nach den beiden in der Fehlermeldung angegebenen Ansprüchen gesucht.Update HINWEIS: Dies sollte nicht erforderlich sein. Sie können die fehlenden Ansprüche zu Ihrer ClaimsIdentity hinzufügen, wenn der Benutzer angemeldet ist.
Beachten Sie, dass einer der Ansprüche möglicherweise bereits von früher vorhanden ist und Sie eine Fehlermeldung mit doppelten Ansprüchen erhalten, wenn Sie beide hinzufügen. Wenn ja, fügen Sie einfach den fehlenden hinzu.
quelle
In Global.asax.cs
1. Fügen Sie diese Namespaces hinzu
2. Fügen Sie diese Zeile in der Methode Application_Start hinzu:
quelle
funktioniert für meinen Fall Ich verwende ADFS-Authentifizierung.
quelle