অ্যান্টি-ফোরজি টোকেন ইস্যু (এমভিসি 5)


122

জালিয়াতি বিরোধী টোকেনটিতে আমার একটি সমস্যা রয়েছে :( আমি আমার নিজস্ব ব্যবহারকারী শ্রেণি তৈরি করেছি যা ভাল কাজ করেছে তবে আমি যখনই অ্যাকাউন্ট / নিবন্ধন পৃষ্ঠাতে যাব তখন আমি একটি ত্রুটি পাচ্ছি The ত্রুটিটি হ'ল:

' Http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name ઓળખાણকারী ' বা ' http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider ' টাইপের একটি দাবি ছিল সরবরাহিত দাবিাদির উপস্থিতি নেই। দাবি-ভিত্তিক প্রমাণীকরণের সাথে অ্যান্টি-জালিয়াতি টোকেন সমর্থন সক্ষম করতে, দয়া করে কনফিগার করা দাবি সরবরাহকারী এটি উত্পন্ন দাবী দাবী দৃষ্টান্তগুলিতে এই উভয় দাবি সরবরাহ করছে তা যাচাই করুন। যদি কনফিগার করা দাবী সরবরাহকারী পরিবর্তে কোনও অনন্য সনাক্তকারী হিসাবে আলাদা দাবি ধরণের ব্যবহার করে তবে এটি স্থিতিশীল সম্পত্তি অ্যান্টিফোর্জিসিফাইগ সেট করে কনফিগার করা যেতে পারে niউনিক ক্লেইমটাইপআইডেন্টিফায়ার।

আমি এই নিবন্ধটি পেয়েছি:

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

সুতরাং আমি আমার অ্যাপ্লিকেশন_সার্ট পদ্ধতিটি এতে পরিবর্তন করেছি :

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

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

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}

তবে আমি যখন এটি করি তখন আমি এই ত্রুটিটি পেয়েছি:

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

আমি প্রোফাইলগুলি আমার সংগ্রহস্থলগুলির জন্য কেবল সহজ, দেখতে এটির মতো:

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

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

    string CredentialId { get; set; }
}

এবং ব্যবহারকারী শ্রেণি হ'ল মাইক্রোসফ্ট.এএসপনেট.আইডেন্টিটি.এন্টিটি ফ্রেমওয়ার্ক।উজার ক্লাস। আমার অ্যাকাউন্টকন্ট্রোলার দেখে মনে হচ্ছে:

[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

সেটিংস চেষ্টা করুন (গ্লোবাল.cs এ):

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

33
আমি মনে করি এটি কেন কাজ করে তা লক্ষ করা জরুরী: এটি AntiForgeryক্লাসটি ব্যবহার করতে বলে NameIdentifier(যা ব্যবহারকারী আইডি স্ট্রিংটি খুঁজে পেয়েছে GetUserId)। আমাকে এটি শিখতে সহায়তা করার জন্য মাইক গুডউইনের উত্তরের জন্য ধন্যবাদ!
ম্যাট ডেক্রে

আমি "এন্টিফোর্জিসিফিগ। ইউনিক ক্লেইমটাইপআইডেন্টিফায়ার = দাবি টিপস.নাম চেষ্টা করেছি;" এবং এই ত্রুটিটি পেয়েছে "সিকোয়েন্সে একাধিক মিলের উপাদান রয়েছে", আমার ক্ষেত্রে বেশ কয়েকটি দাবি (নাম, ভূমিকা এবং ইমেল ঠিকানা) রয়েছে। আমি কীভাবে এটি বাছাই করতে পারি?
ধনুকা 777

9
আমি এটি Global.asax.cs এ সেট করেছি
মাইক

6
আপনি যদি ওপেনআইডি (যেমন অ্যাজুরি অ্যাক্টিভেটরেক্টরি) আপনার প্রমাণীকরণ হিসাবে ব্যবহার করেন তবে এটিও সমাধান solution
লোকালম্যান

6
পুরো নেমস্পেস .. দাবিদার টাইপগুলি কোথায় ছিল তা জানতে আমাকে কিছু খনন করতে হয়েছিল। System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier = System.Security.Claims.ClaimTypees.NameIdentifier;
মার্ক রোয়ে

65

আপনি কি জানেন যে আপনার দাবিদার পরিচয় আপনি কী দাবি পেয়েছেন? যদি না:

  1. [ValidateAntiForgeryToken]গুণটি সরান
  2. আপনার নিয়ামকের কোথাও একটি ব্রেকপয়েন্ট রাখুন এবং এতে ব্রেক করুন
  3. তারপরে বর্তমানটি দেখুন ClaimsIdentityএবং দাবিগুলি পরীক্ষা করুন
  4. এমন একটি সন্ধান করুন যা আপনি ভাবেন যে অনন্যভাবে আপনার ব্যবহারকারীকে সনাক্ত করবে
  5. AntiForgeryConfig.UniqueClaimTypeIdentifierযে দাবি টাইপ সেট করুন
  6. [ValidateAntiForgeryToken]বৈশিষ্ট্যটি পিছনে রাখুন

3
সরাসরি চামচ ফিডের উত্তর সরবরাহ করা ছাড়াও, এটি পটভূমিটি বলে এবং স্ব আবিষ্কার আবিষ্কার করে। :) অনেক অনেক ধন্যবাদ
নিতিনসিংহ

2
6. [ValidateAntiForgeryToken]বৈশিষ্ট্যটি পিছনে রাখুন
স্কট ফ্রেলে

1
এটা সত্যিই আমাকে সাহায্য করেছে। এটি প্রমাণিত হয়েছে যে আমার লোকালহোস্টে চালিত অন্য অ্যাপ্লিকেশনটিতে আমার দাবি রয়েছে, আমার আবেদনে যেখানে কোনও দাবী ব্যবহার করা হয়নি (এজন্য দাবির জিনিসটি আমার কাছে অদ্ভুত লাগছিল)। সুতরাং আমি যখন অন্য অ্যাপ্লিকেশনটি থেকে লগ আউট করেছি তখন দাবিগুলি চলে গিয়েছিল এবং ত্রুটিটিও ছিল। লাইভ-টেস্ট-পরিবেশে এই সাইটগুলি আরও পৃথক করা হয়। সুতরাং আমি মনে করি আমার উপরে উল্লিখিত সমাধানটি প্রয়োজন তবে কেবল স্থানীয় উন্নয়নের জন্য।
মিশেল

26

কেবল এটি Global.asax.cs এ রাখুন

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;

ধন্যবাদ। আমি যা পাই না তা হ'ল আমাকে কেন এই পরিবর্তন করতে হয়েছিল, আমি গতরাতে আমার কোডটি নিয়ে কয়েকটি ভিন্ন সমস্যা সমাধান করেছি এবং সবকিছু ঠিকঠাক কাজ করেছে। কোনও পরিবর্তন না করেই আমি এটি অন্য মেশিনে পরীক্ষা করেছি এবং এটি কয়েক মিনিট আগে পর্যন্ত কাজ করেছিল।
আর্টোরিয়াস 2718

14

ছদ্মবেশী উইন্ডোতে খোলা লিঙ্কটি চেষ্টা করুন বা সেই ডোমেন (যেমন লোকালহোস্ট) থেকে কুকি সাফ করুন।


কেন এটি কাজ করে এবং সমস্যার কারণ কী?
মোক

এটি কাজ করে কারণ আপনার যখন অবৈধ নাম পরিচয়দাতা দিয়ে একটি সেশন কুকি রয়েছে, তখন সার্ভারটি লগ-ইন পৃষ্ঠাতে ব্যবহারকারীকে পুনঃনির্দেশ না করে এবং সঠিক নাম পরিচয়দায়ক না পেয়ে অবৈধ শনাক্তকারীকে ব্যবহার করার চেষ্টা করে।
21:28

3

সম্পাদনা করুন: এই মুহুর্তে এই সমস্যার আরও বেশি বোঝার পরে আপনি নীচে আমার উত্তর উপেক্ষা করতে পারেন।

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;Global.asax.cs এর অ্যাপ্লিকেশন_স্টার্ট () এ সেট করা আমার জন্য এটি স্থির করে। যদিও আমার কাছে দাবি http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifierসেট আছে, আমি মূল প্রশ্নের মতো একই ত্রুটি পেয়েছি। তবে এটি উপরে নির্দেশ করে যেমন কোনওভাবে কাজ করে।



এমভিসি 4 দিয়ে শুরু করে অ্যান্টি-জালিয়াতি-টোকেনটি 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
আমি বুঝতে পারছি আপনি কেন ব্যবহারকারী / আইডিটিকে "/ নাম পরিচয়দাতা" হিসাবে ব্যবহার করছেন তবে আপনি কেন ব্যবহারকারী / আইডিটিকে "/ পরিচয়পোষক" হিসাবে রাখছেন?
অ্যারোনএলএস

2

Global.asax.cs এ,

1. এই নেমস্পেসগুলি যুক্ত করুন

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

2. পদ্ধতিতে অ্যাপ্লিকেশন_সামগ্রীতে এই লাইনটি যুক্ত করুন:

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

উপরে বর্ণিত
উত্তরগুলির

Usings যোগ করার জন্য ধন্যবাদ। @ নিতিনসিংহ আমি মনে করি এটি আরও বেশি মূল্য যুক্ত করে কারণ আমার প্রকল্পে কোন তিনটি সম্ভাব্য নেমস্পেস ব্যবহার করতে হবে তা আমি জানতাম না।
কেইশা ডাব্লু

আপনি যখনই কোনও নতুন কার্যকারিতা যুক্ত করবেন, তখন এটি সঠিক উল্লেখের জন্য জিজ্ঞাসা করবে। এটি
সংকলিত

0
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;

আমার ক্ষেত্রে কাজ করে আমি ADFS প্রমাণীকরণ ব্যবহার করছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.