एंटी-जालसाजी टोकन मुद्दा (एमवीसी 5)


122

मुझे विरोधी जालसाजी टोकन के साथ एक समस्या हो रही है :( मैंने अपना उपयोगकर्ता वर्ग बनाया है जो ठीक काम करता है लेकिन अब जब भी मैं / खाता / रजिस्टर पृष्ठ पर जाता हूं तो मुझे एक त्रुटि मिल रही है । त्रुटि है:

' Http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier ' या ' http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identlproproider ' का दावा था प्रदान किए गए दावे पर मौजूद नहीं है। दावों पर आधारित प्रमाणीकरण के साथ विरोधी जालसाजी टोकन समर्थन को सक्षम करने के लिए, कृपया सत्यापित करें कि कॉन्फ़िगर किया गया दावा प्रदाता इन दोनों दावों को प्रदान कर रहा है, जो दावा करता है कि यह उत्पन्न करता है। यदि कॉन्फ़िगर किया गया दावा प्रदाता इसके बजाय एक अलग पहचानकर्ता के रूप में एक अद्वितीय पहचानकर्ता का उपयोग करता है, तो इसे स्थैतिक संपत्ति AntiForgeryConfig.UniqueClaimTypeIdentifier पर सेट करके कॉन्फ़िगर किया जा सकता है।

मुझे यह लेख मिला:

http://stack247.wordpress.com/2013/02/22/antiforgerytoken-a-claim-of-type-nameidentifier-or-identityprovider-was-not-present-on-provided-claimsidentity/

इसलिए मैंने अपनी Application_Start विधि को इसमें बदल दिया :

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}

लेकिन जब मैं ऐसा करता हूं, मुझे यह त्रुटि मिलती है:

प्रदान किए गए ClaimsIdentity पर ' http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress ' का दावा मौजूद नहीं था।

क्या किसी ने पहले इसका सामना किया है? यदि हां, तो क्या आप जानते हैं कि इसे कैसे हल किया जाए?

अग्रिम में चीयर्स,
r3plica

अपडेट १

यहाँ मेरा कस्टम उपयोगकर्ता वर्ग है:

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>
{
}

मैं अपनी रिपॉजिटरी के लिए प्रोफाइल सरल हूं, इस तरह दिखता है:

public interface IProfile
{
    string Id { get; set; }
    string CompanyId { get; set; }

    string UserName { get; set; }
    string Email { get; set; }

    string CredentialId { get; set; }
}

और उपयोगकर्ता वर्ग Microsoft.AspNet.Identity.EntityFramework.User वर्ग है। मेरा खाता नियंत्रक इस तरह दिखता है:

[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);
        }
    }
}

यह [ValidateAntiForgeryToken] विशेषता के साथ सजाया जाता था , लेकिन यह वह जगह है जहां इसने काम करना बंद कर दिया।

मुझे आशा है कि यह पर्याप्त कोड है :)


क्या आप हमें कस्टम उपयोगकर्ता वर्ग दिखा सकते हैं और आपने इसका उपयोग कैसे किया?
लॉस्ट इनकंप्यूटर

मैंने कस्टम उपयोगकर्ता वर्ग जोड़ा है, साथ ही मैं इसका उपयोग कैसे कर रहा हूं।
r3plica

आप बीटा संस्करण का उपयोग कर रहे हैं। मेरा सुझाव है कि आप रिलीज़ संस्करण में अपग्रेड करें, फिर देखें कि क्या समस्या अभी भी है।
लॉस्ट इनकंप्यूटर

जवाबों:


230

सेटिंग का प्रयास करें (Global.cs में):

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

33
मुझे लगता है कि यह नोट करना महत्वपूर्ण है कि यह क्यों काम करता है: यह AntiForgeryकक्षा को उपयोग करने के लिए कहता है NameIdentifier(जो उपयोगकर्ता आईडी स्ट्रिंग द्वारा पाया जाता है GetUserId)। यह जानने में मेरी मदद करने के लिए माइक गुडविन के उत्तर के लिए धन्यवाद!
मैट डेके

मैंने "AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;" और यह त्रुटि मिली "अनुक्रम में एक से अधिक मिलान तत्व हैं", मेरे मामले में कई दावे (नाम, भूमिका और ईमेलड्रेस) हैं। मैं इसे कैसे सुलझा सकता हूं?
धानुका May११

9
मैंने इसे Global.asax.cs
माइक टैवेने

6
यदि आप OpenId (यानी Azure ActiveDirectory) का उपयोग अपने प्रमाणिकता के रूप में कर रहे हैं तो यह भी समाधान है।
फ़िशरमैन

6
पूर्ण नामस्थान .. मुझे यह पता लगाने के लिए कुछ खुदाई करनी थी कि क्लेमटाइप्स कहां आयोजित किया गया था। सिस्टम।
मार्क रोवे

65

क्या आप जानते हैं कि आपके दावे में क्या दावे आते हैं? अगर नहीं:

  1. [ValidateAntiForgeryToken]विशेषता निकालें
  2. अपने कंट्रोलर में कहीं ब्रेकपॉइंट लगाएं और उस पर ब्रेक लगाएं
  3. फिर वर्तमान को देखें ClaimsIdentityऔर दावों की जांच करें
  4. वह खोजें जो आपको लगता है कि विशिष्ट रूप से आपके उपयोगकर्ता की पहचान करेगा
  5. AntiForgeryConfig.UniqueClaimTypeIdentifierउस दावे प्रकार पर सेट करें
  6. [ValidateAntiForgeryToken]विशेषता वापस रखो

3
प्रत्यक्ष चम्मच फ़ीड उत्तर प्रदान करने से अधिक, यह एक पृष्ठभूमि बताता है और आत्म खोज को सक्षम करता है। :) बहुत बहुत धन्यवाद
NitinSingh

2
6. वापस [ValidateAntiForgeryToken]विशेषता रखो
स्कॉट फ्रेली

1
इसने वास्तव में मेरी मदद की। यह पता चला है कि मुझे अपने लोकलहोस्ट पर चल रहे एक अन्य एप्लिकेशन में, मेरे आवेदन में, जहां कोई दावे का उपयोग नहीं किया गया है (जिसके कारण दावे की बात मुझे अजीब लगी)। इसलिए जब मैंने अन्य एप्लिकेशन से लॉग इन किया, तो दावे समाप्त हो गए थे और इसलिए त्रुटि हुई थी। लाइव-परीक्षण- पर्यावरण पर ये साइटें अलग हो जाती हैं। इसलिए मुझे लगता है कि मुझे उपर्युक्त समाधान की आवश्यकता है, लेकिन केवल स्थानीय विकास के लिए।
मिशेल

26

बस इसे Global.asax.cs में डालें

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;

धन्यवाद। जो कुछ मुझे नहीं मिला वह यह है कि मुझे यह बदलाव क्यों करना पड़ा, मैंने कल रात अपने कोड के साथ कुछ अलग मुद्दे तय किए और सब कुछ ठीक काम कर गया। बिना कुछ बदले, मैंने एक और मशीन पर यह परीक्षण किया और यह सब कुछ मिनट पहले तक काम करता था।
आर्टोरियस 2718

14

गुप्त विंडो में लिंक खोलने की कोशिश करें या उस डोमेन (यानी लोकलहोस्ट) से कुकी को साफ़ करें।


यह काम क्यों करता है और समस्या का कारण क्या है?
मोक

यह काम करता है क्योंकि जब आपके पास अमान्य नेमफीडिफ़ायर के साथ एक सत्र कुकी होती है, तो सर्वर उपयोगकर्ता को लॉग-इन पृष्ठ पर पुनर्निर्देशित किए बिना अमान्य पहचानकर्ता का उपयोग करने और उचित नेम पहचानकर्ता प्राप्त करने का प्रयास करता है।
रॉवेल

3

संपादित करें: इस समय इस समस्या की अधिक समझ होने के कारण, आप नीचे दिए गए मेरे उत्तर की अवहेलना कर सकते हैं।

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;Global.asax.cs के Application_Start () में सेट करना मेरे लिए इसे निर्धारित करता है। भले ही मेरे पास दावा http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifierसेट हो, मुझे मूल प्रश्न के समान त्रुटि मिलती है। लेकिन यह इंगित करता है कि ऊपर किसी तरह काम करता है।



MVC4 के साथ शुरू होने वाला एंटी-जालसाजी-टोकन User.Identity.Nameअद्वितीय पहचानकर्ता के रूप में उपयोग नहीं करता है । इसके बजाय यह त्रुटि संदेश में दिए गए दो दावों की तलाश करता है।

अद्यतन नोट: इसकी आवश्यकता नहीं होनी चाहिए जब आप उपयोगकर्ता द्वारा लॉग इन किया जा रहा हो, तो आप अपने दावे में अनुपलब्ध दावे को जोड़ सकते हैं, जैसे:

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));

ध्यान दें कि दावों में से एक पहले से ही हो सकता है, और यदि आप दोनों जोड़ते हैं, तो आपको डुप्लिकेट दावों के साथ एक त्रुटि मिलेगी। यदि ऐसा है, तो बस एक लापता जोड़ें।


1
मैं समझता हूँ कि आप userId को "/ nameidentifier" के रूप में क्यों उपयोग कर रहे हैं, लेकिन आप userId में "/ Identprovider" के रूप में क्यों डाल रहे हैं?
19

2

Global.asax.cs में,

1. इन नामस्थानों को जोड़ें

using System.Web.Helpers;
using System.Security.Claims;

2. इस लाइन को विधि में जोड़ें Application_Start:

 protected void Application_Start()
 {
       .......
       AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;
 } 

ऊपर दिए गए उत्तर की तुलना में यह किसी भी अधिक मूल्य को कैसे जोड़ता है
नितिनसिंह

Usings जोड़ने के लिए धन्यवाद। @NitinSingh मुझे लगता है कि अधिक मूल्य जोड़ता है क्योंकि मुझे नहीं पता था कि मेरी परियोजना में तीन संभावित नामस्थानों में से कौन सा उपयोग करना है।
कीशा डब्ल्यू

जब भी आप एक नई कार्यक्षमता जोड़ते हैं, तो यह सही संदर्भ मांगेगा। एक बार जब यह संकलित हो जाता है, तो आपको सही क्लिक पर
रिफलेक्टर

0
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;

मेरे मामले के लिए काम करता है मैं ADFS प्रमाणीकरण का उपयोग कर रहा हूँ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.