এএসপি.নেট এমভিসি - কাস্টম IIdentity বা আইপিআরসিস্টাল সেট করুন


650

আমার মোটামুটি সহজ কিছু করা দরকার: আমার এএসপি.নেট এমভিসি অ্যাপ্লিকেশনটিতে, আমি একটি কাস্টম IIdentity / IPr پرنسپل সেট করতে চাই। যেটি সহজ / আরও উপযুক্ত। আমি ডিফল্ট প্রসারিত করতে যাতে আমি ভালো কিছু কল করতে User.Identity.Idএবং User.Identity.Role। কিছুই অভিনব, কিছু অতিরিক্ত সম্পত্তি।

আমি প্রচুর নিবন্ধ এবং প্রশ্নগুলি পড়েছি তবে আমার মনে হচ্ছে আমি এটি আসলে তুলনায় আরও শক্ত করে তুলছি। আমি ভেবেছিলাম এটা সহজ হবে। যদি কোনও ব্যবহারকারী লগইন করে, আমি একটি কাস্টম IIdentity সেট করতে চাই। তাই আমি ভেবেছিলাম, আমি Application_PostAuthenticateRequestআমার গ্লোবাল.এক্স্যাক্সে প্রয়োগ করব। যাইহোক, এটি প্রতিটি অনুরোধের জন্য আহ্বান জানানো হয়, এবং আমি প্রতিটি অনুরোধে ডাটাবেসটিতে কল করতে চাই না যা ডাটাবেস থেকে সমস্ত ডেটা অনুরোধ করবে এবং একটি কাস্টম আইপিআরসিঙ্কাল বস্তুতে রাখবে। এটি খুব অপ্রয়োজনীয়, ধীর এবং ভুল জায়গায় (সেখানে ডাটাবেস কল করা) বলে মনে হচ্ছে তবে আমি ভুল হতে পারি। বা অন্য কোথা থেকে আসে তথ্য?

সুতরাং আমি ভেবেছি, যখনই কোনও ব্যবহারকারী লগ ইন করবে তখন আমি আমার সেশনে কিছু প্রয়োজনীয় পরিবর্তনশীল যুক্ত করতে পারি, যা আমি Application_PostAuthenticateRequestইভেন্ট হ্যান্ডলারের কাস্টম IIdentity এ যুক্ত করি । তবে কি আমার Context.Sessionনেই null, তাই যে যেতে উপায় নয়।

আমি এখন একদিন ধরে এটি নিয়ে কাজ করছি এবং আমি অনুভব করছি যে আমি কিছু মিস করছি। এটি করা খুব কঠিন হওয়া উচিত নয়, তাই না? আমি এগুলি নিয়ে আসা সমস্ত (আধা) সম্পর্কিত স্টাফকেও কিছুটা বিভ্রান্ত করছি। MembershipProvider, MembershipUser, RoleProvider, ProfileProvider, IPrincipal, IIdentity, FormsAuthentication.... অ্যাম আমি শুধুমাত্র এক যারা খুব বিভ্রান্তিকর খুঁজে বের করে এই?

কেউ যদি অতিরিক্ত অতিরিক্ত ঝাঁকুনি ছাড়াই আমাকে একটি আইডেন্ডেন্টিতে কিছু অতিরিক্ত ডেটা সঞ্চয় করার জন্য একটি সহজ, মার্জিত এবং দক্ষ সমাধান বলতে পারে .. তবে দুর্দান্ত হবে! আমি জানি এসও তেও একই রকম প্রশ্ন রয়েছে তবে আমার যে উত্তরটি প্রয়োজন তা যদি সেখানে থাকে তবে আমার অবশ্যই অবহেলা করা উচিত।


1
হাই ডোমি, এটি কেবলমাত্র ডেটা সংরক্ষণের সংমিশ্রণ যা কখনই পরিবর্তিত হয় না (কোনও ব্যবহারকারী আইডির মতো) বা সরাসরি কুকিকে আপডেট করার পরে ব্যবহারকারী সরাসরি ডেভুবাল্ট পরিবর্তন করে যা কুকির মধ্যে এখনই প্রতিফলিত হতে পারে। যদি কোনও ব্যবহারকারী এটি করে, আমি কেবল নতুন ডেটা সহ কুকি আপডেট করি। তবে আমি চেষ্টা করি যে প্রায়শই পরিবর্তন হয় এমন ডেটা সংরক্ষণ না করে।
রাজ্জি

26
এই প্রশ্নের 36k দর্শন এবং অনেকগুলি আপগেট রয়েছে। এটি কি সত্যিই সাধারণ প্রয়োজন - এবং যদি তাই হয় তবে এই সমস্ত 'কাস্টম স্টাফ' এর চেয়ে ভাল উপায় নেই?
সাইমন_উইভার

2
@ সিমন_উইভার এএসপি.এনইটি পরিচয় জানা আছে, যা এনক্রিপ্ট করা কুকিতে অতিরিক্ত কাস্টম তথ্যকে আরও সহজে সমর্থন করে।
জন

1
আমি আপনার সাথে একমত, সেখানে অনেক তথ্য হয় আপনার মত পোস্ট MemberShip..., Principal, Identity। প্রমাণীকরণের সাথে কাজ করার জন্য এএসপি.নেটকে এটিকে সহজ, সহজ এবং সর্বাধিক দুটি পদ্ধতির করা উচিত।
ব্রডব্যান্ড

1
@ সিমন_উইভার এটি পরিষ্কারভাবে দেখায় যে আরও সহজতর আরও নমনীয় পরিচয় ব্যবস্থা আইএমএইচও-র চাহিদা রয়েছে।
নিকো

উত্তর:


838

আমি এখানে এটি কিভাবে।

আমি আইআইডিন্টিয়ালটি আইআইডেন্টিটির পরিবর্তে ব্যবহার করার সিদ্ধান্ত নিয়েছি কারণ এর অর্থ হ'ল আইআইডেন্টিটি এবং আইপিআরসিস্ট্যানাল উভয়ই প্রয়োগ করতে হবে না।

  1. ইন্টারফেস তৈরি করুন

    interface ICustomPrincipal : IPrincipal
    {
        int Id { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
    }
  2. CustomPrincipal

    public class CustomPrincipal : ICustomPrincipal
    {
        public IIdentity Identity { get; private set; }
        public bool IsInRole(string role) { return false; }
    
        public CustomPrincipal(string email)
        {
            this.Identity = new GenericIdentity(email);
        }
    
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
  3. কাস্টমপ্রিন্সিটালসরিয়ালাইজমডেল - ফর্মস অ্যাটেন্টিফিকেশন টিকিট অবজেক্টে ইউজারডাটা ক্ষেত্রে কাস্টম তথ্য সিরিয়ালাইজ করার জন্য।

    public class CustomPrincipalSerializeModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
  4. লগইন পদ্ধতি - কাস্টম তথ্য সহ একটি কুকি সেট আপ

    if (Membership.ValidateUser(viewModel.Email, viewModel.Password))
    {
        var user = userRepository.Users.Where(u => u.Email == viewModel.Email).First();
    
        CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
        serializeModel.Id = user.Id;
        serializeModel.FirstName = user.FirstName;
        serializeModel.LastName = user.LastName;
    
        JavaScriptSerializer serializer = new JavaScriptSerializer();
    
        string userData = serializer.Serialize(serializeModel);
    
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                 1,
                 viewModel.Email,
                 DateTime.Now,
                 DateTime.Now.AddMinutes(15),
                 false,
                 userData);
    
        string encTicket = FormsAuthentication.Encrypt(authTicket);
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        Response.Cookies.Add(faCookie);
    
        return RedirectToAction("Index", "Home");
    }
  5. Global.asax.cs - কুকি পড়া এবং HttpContext.User অবজেক্টের প্রতিস্থাপন, এটি পোস্টআউটিক্যান্টিক্যাস্ট অনুসন্ধানকে ওভাররাইড করে সম্পন্ন করা হয়

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    
        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    
            JavaScriptSerializer serializer = new JavaScriptSerializer();
    
            CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
    
            CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
            newUser.Id = serializeModel.Id;
            newUser.FirstName = serializeModel.FirstName;
            newUser.LastName = serializeModel.LastName;
    
            HttpContext.Current.User = newUser;
        }
    }
  6. রেজার ভিউগুলিতে অ্যাক্সেস

    @((User as CustomPrincipal).Id)
    @((User as CustomPrincipal).FirstName)
    @((User as CustomPrincipal).LastName)

এবং কোডে:

    (User as CustomPrincipal).Id
    (User as CustomPrincipal).FirstName
    (User as CustomPrincipal).LastName

আমি মনে করি কোডটি স্ব-ব্যাখ্যামূলক। যদি তা না হয় তবে আমাকে জানান।

অ্যাক্সেসটিকে আরও সহজ করার জন্য আপনি একটি বেস কন্ট্রোলার তৈরি করতে এবং প্রত্যাবর্তিত ব্যবহারকারী অবজেক্ট (HttpContext.User) ওভাররাইড করতে পারেন:

public class BaseController : Controller
{
    protected virtual new CustomPrincipal User
    {
        get { return HttpContext.User as CustomPrincipal; }
    }
}

এবং তারপরে, প্রতিটি নিয়ামকের জন্য:

public class AccountController : BaseController
{
    // ...
}

যা আপনাকে এই জাতীয় কোডে কাস্টম ক্ষেত্রগুলি অ্যাক্সেস করার অনুমতি দেবে:

User.Id
User.FirstName
User.LastName

তবে এটি অভ্যন্তরীণ ভিউগুলিতে কাজ করবে না। তার জন্য আপনাকে একটি কাস্টম ওয়েবভিউপেজ বাস্তবায়ন তৈরি করতে হবে:

public abstract class BaseViewPage : WebViewPage
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

এটিকে ভিউজ / ওয়েবকনফাইগে একটি ডিফল্ট পৃষ্ঠা টাইপ করুন:

<pages pageBaseType="Your.Namespace.BaseViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
  </namespaces>
</pages>

এবং দর্শনে, আপনি এটির মতো এটি অ্যাক্সেস করতে পারেন:

@User.FirstName
@User.LastName

9
সুন্দর বাস্তবায়ন; আপনার কাস্টম প্রিন্সিপালকে কোনও রোল প্রিন্সিপালের পরিবর্তে রোলম্যানেজারমডুলের দিকে নজর রাখুন। এটি আমার প্রচুর বেদনা ঘটিয়েছিল
ডেভিড কেভেনি

9
ঠিক আছে আমি সমাধানটি খুঁজে পেয়েছি, কেবল একটি অন্য সুইচ যুক্ত করুন যা ইমেল হিসাবে "" (খালি স্ট্রিং) পাস করবে এবং পরিচয় বেনামে থাকবে।
পিয়েরে-আলাইন ভিজিয়েন্ট

3
ডেটটাইম.নিউ.এডডমিনসস (এন) ... কীভাবে এটি তৈরি করা যায় যাতে এটি এন মিনিটের পরে ব্যবহারকারীকে লগআউট না করে, লগ-ইন করা ব্যবহারকারী কি স্থির রাখতে পারবেন (উদাহরণস্বরূপ যখন ব্যবহারকারী 'আমাকে মনে রাখবেন' চেক করবেন)?
1110

4
আপনি WebApiController ব্যবহার করে থাকেন, আপনি সেট করতে হবে Thread.CurrentPrincipalApplication_PostAuthenticateRequestজন্য কাজ যেমন ওপর নির্ভর করে নাHttpContext.Current.User
জনাথন Levison

3
@ অভিনব গুজ্জর FormsAuthentication.SignOut();আমার পক্ষে ভাল কাজ করে।
লুকপি

109

আমি সরাসরি এএসপি.নেট এমভিসির পক্ষে কথা বলতে পারি না, তবে এএসপি.নেট ওয়েব ফর্মগুলির জন্য, কৌশলটি হ'ল FormsAuthenticationTicketএকবার ব্যবহারকারীর প্রমাণীকরণ হওয়ার পরে এটি একটি কুকি তৈরি করা এবং এটিকে এনক্রিপ্ট করা উচিত। এইভাবে, আপনাকে কেবল একবার ডাটাবেস কল করতে হবে (বা AD বা আপনি যাচাই করতে যা ব্যবহার করছেন) এবং পরবর্তী প্রতিটি অনুরোধ কুকিতে সঞ্চিত টিকিটের ভিত্তিতে প্রমাণীকরণ করবে।

এ সম্পর্কে একটি ভাল নিবন্ধ: http://www.ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html (ভাঙা লিঙ্ক)

সম্পাদনা:

যেহেতু উপরের লিঙ্কটি নষ্ট হয়ে গেছে, তাই আমি উপরে তার উত্তরে লূকপি'র সমাধানটি প্রস্তাব করব: https://stackoverflow.com/a/10524305 - আমি স্বীকৃত উত্তরটি সেই একটিতে পরিবর্তন করার পরামর্শও দেব।

2 সম্পাদনা করুন: ভাঙা লিঙ্কের বিকল্প: https://web.archive.org/web/20120422011422/http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html


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

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

3
আপনি যদি এখানে থাকেন তবে আপনি লুকের সমাধানটি দেখুন
মিনকো

2
আমি এই পদ্ধতির সাথে সর্বদা সর্বাধিক কুকি আকার ( স্ট্যাকওভারফ্লো.com/ জিজ্ঞাসা / 8706924/… ) ছাড়িয়ে যাওয়ার সম্ভাবনা নিয়ে উদ্বিগ্ন ছিলাম । আমি সার্ভারে ডেটা রাখার জন্য প্রতিস্থাপন Cacheহিসাবে এটি ব্যবহার করতে চাই Session। কেউ যদি আমাকে বলতে পারেন যে এটি ত্রুটিযুক্ত পদ্ধতির হয়?
রেড তাজ

2
চমৎকার পন্থা। এটির সাথে একটি সম্ভাব্য সমস্যা হ'ল যদি আপনার ব্যবহারকারীর অবজেক্টের কয়েকটি বৈশিষ্ট্যের বেশি থাকে (এবং বিশেষত কোনও নেস্টেড অবজেক্টস) থাকে তবে এনক্রিপ্ট করা মান 4KB এর উপরে চলে গেলে কুকি তৈরি করা নিঃশব্দে ব্যর্থ হয়ে যায় (আঘাত করা খুব সহজ তবে আপনি ভাবতে পারেন)। আপনি যদি কেবল কী ডেটা সঞ্চয় করেন তবে এটি ঠিক আছে তবে আপনাকে বাকি সময়গুলির জন্য ডিবিতে আঘাত করতে হবে। আরেকটি বিবেচনা হ'ল কুকি ডেটা "আপগ্রেড করা" হয় যখন ব্যবহারকারী বস্তুর স্বাক্ষর বা যুক্তি পরিবর্তন হয়।
জেফ্রি হুডিক

63

কাজটি সম্পন্ন করার জন্য এখানে একটি উদাহরণ। বুল ইসভালিডটি কিছু ডেটা স্টোর দেখে সেট করা হয় (যাক আপনার ব্যবহারকারী ডেটা বেসটি বলুন)। ইউজারআইডিআইডি কেবলমাত্র একটি আইডি যা আমি রক্ষণ করছি। আপনি ব্যবহারকারীর ডেটাতে ইমেল ঠিকানার মতো প্রশাসনিক তথ্য যুক্ত করতে পারেন।

protected void btnLogin_Click(object sender, EventArgs e)
{         
    //Hard Coded for the moment
    bool isValid=true;
    if (isValid) 
    {
         string userData = String.Empty;
         userData = userData + "UserID=" + userID;
         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), true, userData);
         string encTicket = FormsAuthentication.Encrypt(ticket);
         HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
         Response.Cookies.Add(faCookie);
         //And send the user where they were heading
         string redirectUrl = FormsAuthentication.GetRedirectUrl(username, false);
         Response.Redirect(redirectUrl);
     }
}

গোলবাল asax আপনার তথ্য পুনরুদ্ধার করতে নিম্নলিখিত কোড যুক্ত করুন

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[
             FormsAuthentication.FormsCookieName];
    if(authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = 
               FormsAuthentication.Decrypt(authCookie.Value);
        // Create an Identity object
        //CustomIdentity implements System.Web.Security.IIdentity
        CustomIdentity id = GetUserIdentity(authTicket.Name);
        //CustomPrincipal implements System.Web.Security.IPrincipal
        CustomPrincipal newUser = new CustomPrincipal();
        Context.User = newUser;
    }
}

আপনি যখন পরে তথ্যটি ব্যবহার করতে যাচ্ছেন, আপনি নীচে আপনার কাস্টম অধ্যক্ষটি অ্যাক্সেস করতে পারেন।

(CustomPrincipal)this.User
or 
(CustomPrincipal)this.Context.User

এটি আপনাকে কাস্টম ব্যবহারকারীর তথ্য অ্যাক্সেস করার অনুমতি দেবে।


2
এফওয়াইআই - এটি রিকোয়েস্ট.কুকিজ [] (বহুবচন)
ড্যান এস্পারজা

10
থ্রেড.কন্টেনার প্রিন্সিপাল পাশাপাশি কনটেক্সট সেট করতে ভুলবেন না Custom কাস্টমপ্রিন্সিপলটির ব্যবহারকারী।
রাশ ক্যাম

6
GetUserIdentity () কোথা থেকে আসে?
রায়ান

আমি মন্তব্যে যেমন উল্লেখ করেছি, এটি System.Web.Security.IIdentity এর একটি বাস্তবায়ন দেয়। গুগল সেই ইন্টারফেস সম্পর্কে
শ্রীবন্ত আত্তনকে

16

এমভিসি আপনাকে অন-অনুমোদিত পদ্ধতি সরবরাহ করে যা আপনার নিয়ামক ক্লাস থেকে স্তব্ধ হয়ে যায়। বা, আপনি অনুমোদনের জন্য একটি কাস্টম অ্যাকশন ফিল্টার ব্যবহার করতে পারেন। এমভিসি এটি করা বেশ সহজ করে তোলে। আমি এই সম্পর্কে একটি ব্লগ পোস্ট পোস্ট। http://www.bradygaster.com/post/custom-authentication-with-mvc-3.0


তবে সেশনটি হারিয়ে যেতে পারে এবং ব্যবহারকারী এখনও প্রমাণীকরণ করতে পারে। না?
ড্রাগগুফ

@ গ্রাডি গ্যাস্টার, আমি আপনার ব্লগ পোস্টটি পড়েছি (ধন্যবাদ!), কেন কেউ কেউ "অনঅরাইজাইটি ()" গ্লোবাল.এক্সএক্স এন্ট্রি সম্পর্কিত আপনার পোস্টে উল্লিখিত হিসাবে "" প্রমাণীকরণের আবেদন (..) "অন্যের দ্বারা উল্লিখিত হবে? উত্তর? নীতি ব্যবহারকারীকে নির্ধারণের ক্ষেত্রে কি একজনের চেয়ে অন্যের চেয়ে বেশি পছন্দ হয়?
রায়লভলেস

10

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

using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Security.Principal;

    namespace SomeSite.Web.Helpers
    {
        public static class UserHelpers
        {
            public static bool IsEditor(this IPrincipal user)
            {
                return null; //Do some stuff
            }
        }
    }

তারপরে কেবলমাত্র ওয়েবকনফিগ অঞ্চলে একটি রেফারেন্স যুক্ত করুন এবং দেখুন নীচের মত এটি কল করুন।

@User.IsEditor()

1
আপনার সমাধানে, আমাদের আবারও প্রতিবার ডাটাবেস কল করা দরকার। কারণ ব্যবহারকারীর অবজেক্টের কাস্টম বৈশিষ্ট্য নেই। এটির কেবলমাত্র নাম এবং ইসাথ্যাটেস্টিটেড রয়েছে
ওয়ানসাইফ্রেন্ড

এটি সম্পূর্ণরূপে আপনার বাস্তবায়ন এবং পছন্দসই আচরণের উপর নির্ভর করে। আমার নমুনায় ডাটাবেসের 0 লাইন বা ভূমিকা, যুক্তি রয়েছে। যদি কেউ আইসিনরোল ব্যবহার করে তবে এটি আমার বিশ্বাস বিশ্বাসযোগ্য কুকিতে ক্যাশে দেওয়া যেতে পারে। অথবা আপনি নিজের ক্যাশে যুক্তি প্রয়োগ করেন implement
বেস

3

লুকপির উত্তরের ভিত্তিতে এবং সেটআপে কিছু পদ্ধতি যুক্ত করুন timeoutএবং এতে requireSSLসহযোগিতা করুন Web.config

রেফারেন্স লিঙ্ক

লুুকপি-র পরিবর্তিত কোডসমূহ

1, timeoutউপর ভিত্তি করে সেট করুন Web.ConfigFormsAuthentication.Timeout সময়সীমার মান, যা web.config সংজ্ঞায়িত করা হয় পাবেন। আমি নিম্নলিখিতগুলি একটি ফাংশন হিসাবে আবৃত করেছি, যা ticketপিছনে ফিরে আসে।

int version = 1;
DateTime now = DateTime.Now;

// respect to the `timeout` in Web.config.
TimeSpan timeout = FormsAuthentication.Timeout;
DateTime expire = now.Add(timeout);
bool isPersist = false;

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
     version,          
     name,
     now,
     expire,
     isPersist,
     userData);

2, কনফিগারেশনের উপর ভিত্তি করে কুকিকে সুরক্ষিত রাখতে বা না RequireSSLকনফিগার করুন।

HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
// respect to `RequreSSL` in `Web.Config`
bool bSSL = FormsAuthentication.RequireSSL;
faCookie.Secure = bSSL;

3

ঠিক আছে, সুতরাং আমি খুব পুরানো এই প্রশ্নটিকে টেনে এনে এখানে একটি গুরুতর ক্রিপ্টকিপার, তবে এটির জন্য আরও সহজ সরল পদ্ধতি রয়েছে, যা উপরের @ বেসার্স দ্বারা স্পর্শ করেছিলেন। এবং তা হ'ল সি # এক্সটেনশন পদ্ধতি এবং ক্যাশে (সেশন ব্যবহার করবেন না) এর সংমিশ্রণটি ব্যবহার করা।

প্রকৃতপক্ষে, মাইক্রোসফ্ট ইতিমধ্যে Microsoft.AspNet.Identity.IdentityExtensionsনেমস্পেসে এরকম বেশ কয়েকটি এক্সটেনশন সরবরাহ করেছে । উদাহরণস্বরূপ, GetUserId()একটি এক্সটেনশন পদ্ধতি যা ব্যবহারকারীর আইডি ফেরত দেয়। এছাড়াও রয়েছে GetUserName()এবং FindFirstValue(), যা আইপি প্রিন্সিপালের ভিত্তিতে দাবিগুলি ফিরিয়ে দেয়।

সুতরাং আপনাকে কেবল নেমস্পেস অন্তর্ভুক্ত করতে হবে এবং তারপরে User.Identity.GetUserName()এএসপি.এনইটি পরিচয় দ্বারা কনফিগার করা হিসাবে ব্যবহারকারীদের নাম পেতে কল করুন ।

এটি ক্যাশে করা হয়েছে কিনা তা আমি নিশ্চিত নই, যেহেতু পুরানো এএসপি.নেট পরিচয়টি খোলা সোর্স হয় না, এবং আমি এটির বিপরীতে ইঞ্জিনিয়ারকে বিরক্ত করারও মাথা ঘামাই না। যাইহোক, যদি এটি না হয় তবে আপনি নিজের এক্সটেনশন পদ্ধতিটি লিখতে পারেন, এটি নির্দিষ্ট সময়ের জন্য এই ফলাফলকে ক্যাশে করবে।


কেন "সেশন ব্যবহার করবেন না"?
অ্যালেক্স

@ অজিবিট - কারণ অধিবেশন অবিশ্বাস্য এবং সুরক্ষিত। একই কারণে আপনার কখনই সুরক্ষা উদ্দেশ্যে সেশন ব্যবহার করা উচিত নয়।
এরিক ফানকেনবাশ

"অবিশ্বস্ত" সেশন পুনর্নির্মাণের মাধ্যমে সম্বোধন করা যেতে পারে (খালি থাকলে)। "অনিরাপদ" - সেশন হাইজ্যাকিং থেকে রক্ষা করার উপায় রয়েছে (কেবলমাত্র HTTPS ব্যবহার করে + অন্যান্য উপায়ে)। তবে আমি আসলে আপনার সাথে একমত আপনি কোথায় এটি ক্যাশে হবে? মত তথ্য IsUserAdministratorবা UserEmailইত্যাদি? ভাবছেন HttpRuntime.Cache?
অ্যালেক্স

@জিবিট - এটি একটি বিকল্প বা আপনার যদি এটির থাকে তবে অন্য একটি ক্যাশে করার সমাধান। কিছু সময়ের পরে ক্যাশে প্রবেশের মেয়াদ শেষ হওয়ার বিষয়টি নিশ্চিত করা। সুরক্ষা স্থানীয় সিস্টেমে প্রযোজ্য, যেহেতু আপনি ম্যানুয়ালি কুকিকে পরিবর্তন করতে পারেন এবং সেশন আইডির অনুমান করতে পারেন। মাঝখানে মানুষই একমাত্র উদ্বেগ নয়।
এরিক ফানকেনবাশ

2

ওয়েব ফর্ম ব্যবহারকারীদের জন্য লুকপি কোড যুক্ত করার সাথে (এমভিসি নয়) আপনি যদি আপনার পৃষ্ঠাগুলির পেছনের কোডটিতে অ্যাক্সেসকে সহজ করতে চান তবে কেবল নীচের কোডটি একটি বেস পৃষ্ঠায় যুক্ত করুন এবং আপনার সমস্ত পৃষ্ঠায় বেস পৃষ্ঠাটি পান:

Public Overridable Shadows ReadOnly Property User() As CustomPrincipal
    Get
        Return DirectCast(MyBase.User, CustomPrincipal)
    End Get
End Property

সুতরাং আপনার পেছনের কোডটিতে আপনি কেবল অ্যাক্সেস করতে পারবেন:

User.FirstName or User.LastName

আমি ওয়েব ফর্ম দৃশ্যে যা অনুপস্থিত তা কীভাবে কোডের সাথে একই আচরণটি পাতার সাথে বেঁধে রাখা যায় না, উদাহরণস্বরূপ, পোস্টমডিউলগুলিতে আমি সবসময় প্রতিটি ক্লাসে একটি কাস্ট যুক্ত করা উচিত বা এটি প্রাপ্ত করার জন্য আরও স্মার্ট উপায় আছে?

আপনার উত্তর এবং জন্য ধন্যবাদ LukeP ধন্যবাদ যেহেতু আমি আমার কাস্টম ব্যবহারকারীর জন্য একটি বেস হিসাবে আপনার উদাহরণ ব্যবহার করা (বর্তমানে যা User.Roles, User.Tasks, User.HasPath(int), User.Settings.Timeoutএবং অনেক অন্যান্য চমৎকার জিনিস)


0

আমি লুুকপি দ্বারা প্রস্তাবিত সমাধানটি চেষ্টা করে দেখেছি যে এটি অনুমোদন গুণকে সমর্থন করে না। সুতরাং, আমি এটি কিছুটা সংশোধন করেছি।

public class UserExBusinessInfo
{
    public int BusinessID { get; set; }
    public string Name { get; set; }
}

public class UserExInfo
{
    public IEnumerable<UserExBusinessInfo> BusinessInfo { get; set; }
    public int? CurrentBusinessID { get; set; }
}

public class PrincipalEx : ClaimsPrincipal
{
    private readonly UserExInfo userExInfo;
    public UserExInfo UserExInfo => userExInfo;

    public PrincipalEx(IPrincipal baseModel, UserExInfo userExInfo)
        : base(baseModel)
    {
        this.userExInfo = userExInfo;
    }
}

public class PrincipalExSerializeModel
{
    public UserExInfo UserExInfo { get; set; }
}

public static class IPrincipalHelpers
{
    public static UserExInfo ExInfo(this IPrincipal @this) => (@this as PrincipalEx)?.UserExInfo;
}


    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginModel details, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            AppUser user = await UserManager.FindAsync(details.Name, details.Password);

            if (user == null)
            {
                ModelState.AddModelError("", "Invalid name or password.");
            }
            else
            {
                ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                AuthManager.SignOut();
                AuthManager.SignIn(new AuthenticationProperties { IsPersistent = false }, ident);

                user.LastLoginDate = DateTime.UtcNow;
                await UserManager.UpdateAsync(user);

                PrincipalExSerializeModel serializeModel = new PrincipalExSerializeModel();
                serializeModel.UserExInfo = new UserExInfo()
                {
                    BusinessInfo = await
                        db.Businesses
                        .Where(b => user.Id.Equals(b.AspNetUserID))
                        .Select(b => new UserExBusinessInfo { BusinessID = b.BusinessID, Name = b.Name })
                        .ToListAsync()
                };

                JavaScriptSerializer serializer = new JavaScriptSerializer();

                string userData = serializer.Serialize(serializeModel);

                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                         1,
                         details.Name,
                         DateTime.Now,
                         DateTime.Now.AddMinutes(15),
                         false,
                         userData);

                string encTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
                Response.Cookies.Add(faCookie);

                return RedirectToLocal(returnUrl);
            }
        }
        return View(details);
    }

এবং অবশেষে Global.asax.cs এ

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            PrincipalExSerializeModel serializeModel = serializer.Deserialize<PrincipalExSerializeModel>(authTicket.UserData);
            PrincipalEx newUser = new PrincipalEx(HttpContext.Current.User, serializeModel.UserExInfo);
            HttpContext.Current.User = newUser;
        }
    }

এখন আমি কেবল কল করে ভিউ এবং নিয়ন্ত্রণকারীদের ডেটা অ্যাক্সেস করতে পারি

User.ExInfo()

লগ আউট করতে আমি কেবল কল করি

AuthManager.SignOut();

যেখানে আথ ম্যানেজার

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