2011-01-17 9 views
9

पर मूल HTTP एथ जोड़ना मेरे पास एक डब्ल्यूसीएफ HTTP रीस्ट सेवा है और मैं इसे एक अलग प्रोग्रामिंग भाषा में एक HTTP क्लाइंट के साथ जोड़ता हूं जो अपना कस्टम HTTP लिखता है। मैं डब्ल्यूडब्ल्यूडब्ल्यू-प्रमाणीकरण मूलभूत प्रमाणीकरण समर्थन को अपनी डब्ल्यूसीएफ सेवा में जोड़ना चाहता हूं।डब्ल्यूसीएफ आरईएसटी सेवा

मेरे तरीकों इस तरह दिखेगा:

[WebInvoke(UriTemplate = "widgets", Method = "POST")] 
public XElement CreateWidget(XElement e) 
{ 
... 
} 

क्या यह संभव है मुझे किसी भी तरह भेजे HTTP अनुरोध को फिल्टर करने के लिए तो मैं पहले यह ऊपर CreateWidget की तरह बाकी तरीकों में से प्रत्येक हिट एक वैध मूल प्रमाणीकरण स्ट्रिंग के लिए जाँच कर सकते हैं? नोट: मेरी ऑथ जानकारी मेरे डेटाबेस में stord है।

मूल रूप से मैं अनुरोध शीर्षों में इस के लिए जाँच करना चाहते हैं: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== और फिर मैं अपने आप को कि स्ट्रिंग पार्स और डेटाबेस में यू/p सत्यापित कर सकें।

web.config फ़ाइल इस प्रकार है:

<?xml version="1.0"?> 
<configuration> 

    <connectionStrings> 
    <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Database;Integrated Security=True" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <httpRuntime maxRequestLength="10485760" /> 
    </system.web> 

    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
    </modules> 
    </system.webServer> 

    <system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
    <standardEndpoints> 
     <webHttpEndpoint> 
     <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" /> 
     </webHttpEndpoint> 
    </standardEndpoints> 
    </system.serviceModel> 

</configuration> 

उत्तर

8

मैं भी एक बाकी HTTP WCF सेवा में कस्टम प्रमाणीकरण में रुचि थी और अंत में यह काम करने के लिए मिला है। कहा जा रहा है

मेरा कोड आप एक तरह से यह काम कर रहा करने के लिए दे देंगे, लेकिन मैं इस गाइड जो अधिक गहराई में सब कुछ बताते हैं पढ़ने की सलाह देते: http://wcfsecurityguide.codeplex.com/

पहले, देखने के लिए अपनी Web.Config की system.web भाग बदल इस तरह:

<system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    <httpRuntime maxRequestLength="10485760" /> 
    <authentication mode="None"></authentication> 
    <httpModules> 
    <add name="BasicAuthenticationModule" type="YourNamespace.UserNameAuthenticator" /> 
    </httpModules> 
</system.web> 

तो अपनी परियोजना के लिए एक अन्य फ़ाइल जोड़ें: UserNameAuthenticator.cs

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Web; 
using System.Web.Security; 
using System.Security.Principal; 
using System.ServiceModel.Activation; 

namespace YourNamespace 
{ 
    public class UserNameAuthenticator : IHttpModule 
    { 
     public void Dispose() 
     { 
     } 

     public void Init(HttpApplication application) 
     { 
      application.AuthenticateRequest += new EventHandler(this.OnAuthenticateRequest); 
      application.AuthorizeRequest += new EventHandler(this.OnAuthorizationRequest); 
      application.EndRequest += new EventHandler(this.OnEndRequest); 
     } 

     public bool CustomAuth(string username, string password) 
     { 
      //TODO: Implement your custom auth logic here 
      return true; 
     } 

     public string[] GetCustomRoles(string username) 
     { 
      return new string[] { "read", "write" }; 
     } 

     public void OnAuthorizationRequest(object source, EventArgs eventArgs) 
     { 
      HttpApplication app = (HttpApplication)source; 
      //If you want to handle authorization differently from authentication 
     } 

     public void OnAuthenticateRequest(object source, EventArgs eventArgs) 
     { 
      HttpApplication app = (HttpApplication)source; 
      //the Authorization header is checked if present 
      string authHeader = app.Request.Headers["Authorization"]; 
      if (!string.IsNullOrEmpty(authHeader)) 
      { 
       string authStr = app.Request.Headers["Authorization"]; 
       if (authStr == null || authStr.Length == 0) 
       { 
        // No credentials; anonymous request 
        return; 
       } 
       authStr = authStr.Trim(); 
       if (authStr.IndexOf("Basic", 0) != 0) 
       { 
        //header not correct we do not authenticate 
        return; 
       } 

       authStr = authStr.Trim(); 
       string encodedCredentials = authStr.Substring(6); 
       byte[] decodedBytes = Convert.FromBase64String(encodedCredentials); 
       string s = new ASCIIEncoding().GetString(decodedBytes); 
       string[] userPass = s.Split(new char[] { ':' }); 
       string username = userPass[0]; 
       string password = userPass[1]; 
       //the user is validated against the SqlMemberShipProvider 
       //If it is validated then the roles are retrieved from the 
       //role provider and a generic principal is created 
       //the generic principal is assigned to the user context 
       // of the application 
       if (CustomAuth(username, password)) 
       { 
        string[] roles = GetCustomRoles(username); 
        app.Context.User = new GenericPrincipal(new 
        GenericIdentity(username, "Membership Provider"), roles); 
       } 
       else 
       { 
        DenyAccess(app); 
        return; 
       } 
      } 
      else 
      { 
       //the authorization header is not present 
       //the status of response is set to 401 and it ended 
       //the end request will check if it is 401 and add 
       //the authentication header so the client knows 
       //it needs to send credentials to authenticate 
       app.Response.StatusCode = 401; 
       app.Response.End(); 
      } 
     } 

     public void OnEndRequest(object source, EventArgs eventArgs) 
     { 
      if (HttpContext.Current.Response.StatusCode == 401) 
      { 
       //if the status is 401 the WWW-Authenticated is added to 
       //the response so client knows it needs to send credentials 
       HttpContext context = HttpContext.Current; 
       context.Response.StatusCode = 401; 
       context.Response.AddHeader("WWW-Authenticate", "Basic Realm"); 
      } 
     } 
     private void DenyAccess(HttpApplication app) 
     { 
      app.Response.StatusCode = 401; 
      app.Response.StatusDescription = "Access Denied"; 
      // error not authenticated 
      app.Response.Write("401 Access Denied"); 
      app.CompleteRequest(); 
     } 
    } // End Class 
} //End Namespace 
+0

मैंने सुझाए गए चरणों का पालन किया है, लेकिन मॉड्यूल को कभी भी बुलाया नहीं जाता है। मैंने आईआईएस पर बेसिक ऑथ जोड़ने की कोशिश की लेकिन फिर भी, मॉड्यूल को कॉल नहीं किया जाता है। क्या मैं कुछ भूल रहा हूँ? –

+0

मुझे यकीन नहीं है कि यह मेरे लिए क्यों काम करता है लेकिन शायद इससे संबंधित: http://stackoverflow.com/questions/355261/whats-the-difference-between-system-web-and-system-webserver (मैं था वीएस डिबगिंग ऑटो होस्टेड वेब सर्वर के माध्यम से परीक्षण) –

+0

मुझे मैन्युअल रूप से आईआईएस 7.5 में मॉड्यूल जोड़ना पड़ा। –

3

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

मैं अंत में मिला यह काम कर रहा है और आप अपने ब्लॉग से नमूना कोड डाउनलोड कर सकते हैं: जब तक आप "BasicRealm" बदलने के लिए "BasicRealm = साइट http://sameproblemmorecode.blogspot.com/2011/10/creating-secure-restfull-wcf-service.html

2

बस इस में जोड़ने के लिए, क्रोम लॉगिन संवाद लोड नहीं होगा "OnEndRequest विधि में:

public void OnEndRequest(object source, EventArgs eventArgs) 
    { 
     if (HttpContext.Current.Response.StatusCode == 401) 
     { 
      //if the status is 401 the WWW-Authenticated is added to 
      //the response so client knows it needs to send credentials 
      HttpContext context = HttpContext.Current; 
      context.Response.StatusCode = 401; 
      context.Response.AddHeader("WWW-Authenticate", "Basic Realm=site"); 
     } 
    } 

और धन्यवाद, यह इतना आसान समाधान है।

संबंधित मुद्दे