2010-04-06 17 views
14

में डब्ल्यूसीएफ प्रमाणीकरण सेवा से प्रमाणीकरण कुकी का उपयोग कैसे करें ठीक है, मेरे पास मेरे विशिष्ट परिदृश्य के लिए कोई दस्तावेज़ या ट्यूटोरियल ढूंढने में बहुत कम भाग्य नहीं है।एएसपी.NET एमवीसी अनुप्रयोग

मेरे पास एक एएसपी.NET एमवीसी वेब एप्लिकेशन है जो प्रमाणीकरण और भूमिकाओं (डब्ल्यूसीएफ बैकएंड पर सदस्यता प्रदाताओं के माध्यम से) सहित सभी चीज़ों के लिए डब्ल्यूसीएफ सेवाओं का उपयोग करेगा।

मुझे कोई समस्या नहीं है setting up the authentication services लेकिन यह वेब ऐप में कुकी सेट नहीं करता है। Login method of the service के लिए दस्तावेज़ इंगित करते हैं कि क्रिएटिंगकुकी इवेंट को तारों को संभव बनाना संभव है, लेकिन इसका क्लाइंट पर कोई प्रभाव नहीं पड़ता है (मैंने सेवा पक्ष पर भी कोशिश की है, फिर भी कोई प्रभाव नहीं है)। तो मुझे पता चला कि capture the cookie कैसे करें। मैंने क्लाइंट पर ऑथ कुकी मैन्युअल रूप से सेट करने का प्रयास किया है, लेकिन अब तक यह काम नहीं कर रहा है; डिक्रिप्टिंग पैडिंग के कारण विफल हो जाती है, और सर्वर द्वारा दिए गए एक से कुकी मान सेट करना क्लाइंट द्वारा पठनीय नहीं है।

क्या कोई जानता है कि आपको डब्ल्यूसीएफ प्रमाणीकरण सेवा द्वारा उत्पन्न कुकी का उपयोग कैसे करना है? क्या मुझे लगता है कि सत्र डब्लूसीएफ सर्वर पर प्रबंधित है और बस प्रत्येक पृष्ठ लोड पर सेवा पर IsLoggedIn() की जांच करें?

अग्रिम धन्यवाद।

+0

एमएसडीएन पर अधिक दस्तावेज़ीकरण के माध्यम से पढ़ना, मुझे लगता है कि मेरा परिदृश्य कभी एमएस द्वारा नहीं किया गया था; यदि आप किसी वेबसाइट पर सदस्यता का उपयोग करने जा रहे हैं, तो आप कभी भी डीबी को सीधे मारने के बजाय किसी सेवा को प्रमाणित क्यों करेंगे, ऐसा लगता है कि किसी वेबसाइट को किसी अन्य क्लाइंट के समान ही संभालना होगा, जिसका अर्थ है कि मैन्युअल रूप से कुकीज़ को हथियाने से हेडर और स्वयं का उपयोग करना (एक प्रिंसिपल, ऑथ टिकट आदि बनाना और उन्हें वेबसाइट के उचित हिस्सों में असाइन करना ताकि इसका उपयोग किया जा सके)। अधिक जांच करेगा और उम्मीद है कि पोस्ट का जवाब है ... – tap

उत्तर

11

मैं हाल ही में आपके द्वारा वर्णित वही कार्यक्षमता को लागू करने की कोशिश कर रहा हूं। मैंने इसे निम्नलिखित कोड के साथ काम करने में कामयाब रहा है:

private readonly AuthenticationServiceClient service = new AuthenticationServiceClient(); 

    public void SignIn(string userName, string password, bool createPersistentCookie) 
    { 
     using (new OperationContextScope(service.InnerChannel)) 
     { 
      // login 
      service.Login(userName, password, String.Empty, createPersistentCookie); 

      // Get the response header 
      var responseMessageProperty = (HttpResponseMessageProperty) 
       OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]; 

      string encryptedCookie = responseMessageProperty.Headers.Get("Set-Cookie"); 

      // parse header to cookie object 
      var cookieJar = new CookieContainer(); 
      cookieJar.SetCookies(new Uri("http://localhost:1062/"), encryptedCookie); 
      Cookie cookie = cookieJar.GetCookies(new Uri("http://localhost:1062/"))[0]; 

      FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); 
      if (null != ticket) 
      { 
       //string[] roles = RoleManager.GetRolesFromString(ticket.UserData); 
       HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), null); 
       FormsAuthentication.SetAuthCookie(HttpContext.Current.User.Identity.Name, createPersistentCookie); 
      } 
     } 
    } 

यह वही है जो आपने अपने प्रश्न पर टिप्पणी का वर्णन किया है।

संपादित

मैं यहाँ संदर्भ के लिए इस कोड की सर्वर-साइड भाग पोस्टिंग कर रहा हूँ।

public class HttpResponseMessageInspector : BehaviorExtensionElement, IDispatchMessageInspector, IServiceBehavior 
{ 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 

     HttpRequestMessageProperty httpRequest = request.Properties[HttpRequestMessageProperty.Name] 
     as HttpRequestMessageProperty; 

     if (httpRequest != null) 
     { 
      string cookie = httpRequest.Headers[HttpRequestHeader.Cookie]; 

      if (!string.IsNullOrEmpty(cookie)) 
      { 
       FormsAuthentication.Decrypt(cookie); 
       FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookie); 
       string[] roles = PrincipalHelper.GetUserRoles(authTicket); 
       var principal = new BreakpointPrincipal(new BreakpointIdentity(authTicket), roles); 

       HttpContext.Current.User = principal;     
      } 
      // can deny request here 
     } 

     return null; 
    } 
} 
+0

वाह, मुझे कुछ चाल याद आ गईं .. मुझे देखने दो कि यह कैसे काम करता है और मैं आपके पास वापस आऊंगा। इससे कोई फर्क नहीं पड़ता कि मैं वास्तव में आपके प्रयास की सराहना करता हूं और रुचि लेता हूं :) – tap

+0

यह सतह पर अच्छा दिखता है, लेकिन मुझे वही समस्या दिखाई दे रही है जिसमें मैं भाग गया: System.Security.Cryptography.CryptographicException: पैडिंग अमान्य है और इसे हटाया नहीं जा सकता है। इस त्रुटि पर मेरी धारणा यह है कि चूंकि यह 2 अलग-अलग संदर्भ (क्लाइंट एप्लिकेशन और सेवा अनुप्रयोग) है, तो डिक्रिप्ट/एन्क्रिप्ट संगत नहीं है? आपने इसे कैसे काम पर रखा? फिर से रुचि और प्रयास लेने के लिए धन्यवाद :) – tap

+0

क्या Asp.net एमवीसी और डब्ल्यूसीएफ होस्ट एप्लिकेशन एक ही मशीन पर चल रहा है? यदि नहीं, तो आपको उसी मशीन कुंजी का उपयोग करने के लिए Web.config दोनों सेट करना होगा। देखें [http://msdn.microsoft.com/en-us/library/ms998288.aspx] मेरे सेटअप में, एमवीसी और डब्ल्यूसीएफ सेवा होस्ट दोनों मेरी स्थानीय मशीन पर विजुअल स्टूडियो वेबसेवर के भीतर चल रहे हैं। तो मशीन कुंजी वही होगी। संपादित करें: आप इस कोड को WCF होस्ट Global.cs फ़ाइल को स्पष्ट रूप से एक कुकी भेजने के लिए केवल एक चीज़ को रद्द करने का प्रयास कर सकते हैं: http://msdn.microsoft.com/en-us/library/bb398778% 28v = VS.100% 29.aspx – Karl

2

यह मेरे लिए काम करता ... सबसे पहले सेटअप मेजबान (यहाँ कोड के माध्यम से दिखाया गया है, लेकिन यह भी config में किया जा सकता) के प्रमाणीकरण व्यवहार:

ServiceAuthorizationBehavior author = Description.Behaviors.Find<ServiceAuthorizationBehavior>(); 
author.ServiceAuthorizationManager = new FormCookieServiceAuthorizationManager(); 
author.PrincipalPermissionMode = PrincipalPermissionMode.Custom; 
author.ExternalAuthorizationPolicies = new List<IAuthorizationPolicy> { new CustomAuthorizationPolicy() }.AsReadOnly(); 

और फिर सहायक वर्गों

internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager 
    { 
    public override bool CheckAccess(OperationContext operationContext) 
    { 
     ParseFormsCookie(operationContext.RequestContext.RequestMessage); 
     return base.CheckAccess(operationContext); 
    } 
    private static void ParseFormsCookie(Message message) 
    { 
     HttpRequestMessageProperty httpRequest = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; 
     if (httpRequest == null) return; 

     string cookie = httpRequest.Headers[HttpRequestHeader.Cookie]; 
     if (string.IsNullOrEmpty(cookie)) return; 

     string regexp = Regex.Escape(FormsAuthentication.FormsCookieName) + "=(?<val>[^;]+)"; 
     var myMatch = Regex.Match(cookie, regexp); 
     if (!myMatch.Success) return; 

     string cookieVal = myMatch.Groups["val"].ToString(); 
     FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookieVal); 
     Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), new string[0]); 
    } 
    } 
    internal class CustomAuthorizationPolicy : IAuthorizationPolicy 
    { 
    static readonly string _id = Guid.NewGuid().ToString(); 
    public string Id 
    { 
     get { return _id; } 
    } 

    public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
    { 
     evaluationContext.Properties["Principal"] = Thread.CurrentPrincipal; 
     evaluationContext.Properties["Identities"] = new List<IIdentity> { Thread.CurrentPrincipal.Identity }; 
     return true; 
    } 

    public ClaimSet Issuer 
    { 
     get { return ClaimSet.System; } 
    } 
    } 

और जब AspNetCompatibility सेट किया गया है के लिए है, तो FormCookieServiceAuthorizationManager थोड़ा सरल है:

internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager 
{ 
    public override bool CheckAccess(OperationContext operationContext) 
    { 
     Thread.CurrentPrincipal = HttpContext.Current.User; 
     return base.CheckAccess(operationContext); 
    } 
} 
संबंधित मुद्दे