2012-06-02 12 views
11

asmx web hizmetimde kullanıcı adı ve parola doğrulaması kullanarak temel kimlik doğrulaması uygulamak istiyorum.
WCF kullanmak istemiyorum ve bunun güvenli bir şekilde olmadığını biliyorum, ancak https kullanılmadan temel kimlik doğrulaması kullanmalıyım.Asmx web hizmeti temel kimlik doğrulaması

Benim web hizmeti şu şekildedir:

[WebService(Namespace = "http://www.mywebsite.com/")] 
public class Service1 
{ 
    [WebMethod] 
    public string HelloWorld() 
    { 
     return "Hello world"; 
    } 
} 

Ve bu özel HttpModule'ü kullanın:

public class BasicAuthHttpModule : IHttpModule 
{ 
    void IHttpModule.Init(HttpApplication context) 
    { 
     context.AuthenticateRequest += new EventHandler(OnAuthenticateRequest); 
    } 

    void OnAuthenticateRequest(object sender, EventArgs e) 
    { 
     string header = HttpContext.Current.Request.Headers["Authorization"]; 

     if (header != null && header.StartsWith("Basic")) //if has header 
     { 
      string encodedUserPass = header.Substring(6).Trim(); //remove the "Basic" 
      Encoding encoding = Encoding.GetEncoding("iso-8859-1"); 
      string userPass = encoding.GetString(Convert.FromBase64String(encodedUserPass)); 
      string[] credentials = userPass.Split(':'); 
      string username = credentials[0]; 
      string password = credentials[1]; 

      if(!MyUserValidator.Validate(username, password)) 
      { 
       HttpContext.Current.Response.StatusCode = 401; 
       HttpContext.Current.Response.End(); 
      } 
     } 
     else 
     { 
      //send request header for the 1st round 
      HttpContext context = HttpContext.Current; 
      context.Response.StatusCode = 401; 
      context.Response.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", string.Empty)); 
     } 
    } 

    void IHttpModule.Dispose() 
    { 
    } 
} 

Ve web.config'de bunu kullanmaktan:

<?xml version="1.0"?> 
<configuration> 
    <appSettings/> 
    <connectionStrings/> 
    <system.web> 
     <customErrors mode="Off" /> 
     <compilation debug="true" targetFramework="4.0"/> 
     <authentication mode="None"/> 
    </system.web> 
    <system.webServer> 
     <modules runAllManagedModulesForAllRequests="true"> 
      <add name="BasicAuthHttpModule" 
       type="AuthService.BasicAuthHttpModule, AuthService" /> 
     </modules> 
    </system.webServer> 
</configuration>  

çağrı kodu:

static void Main(string[] args) 
{ 
    var proxy = new Service1.Service1() 
        { 
         Credentials = new NetworkCredential("user1", "[email protected]"), 
         PreAuthenticate = true 
        }; 
    try 
    { 
     var result = proxy.HelloWorld(); 
     Console.WriteLine(result); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.Message); 
    } 
    Console.ReadKey(); 
} 

Bu web hizmetini kullandığımda, hizmet temel kimlik doğrulamasını ister OnAuthenticateRequest yönteminde header değişkeni her zaman sıfırdır ve MyUserValidator.Validate() hiçbir zaman çalışmaz.

DÜZENLEME

kemancı sonuçları:

POST http://www.mywebsite.com/Service1.asmx HTTP/1.1 
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.4927) 
VsDebuggerCausalityData: uIDPo+drc57U77xGu/ZaOdYvw6IAAAAA8AjKQNpkV06FEWDEs2Oja2C+h3kM7dlDvnFfE1VlIIIACQAA 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "http://www.mywebsite.com/HelloWorld" 
Host: www.mywebsite.com 
Content-Length: 291 
Expect: 100-continue 
Connection: Keep-Alive 

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorld xmlns="http://www.mywebsite.com/" /></soap:Body></soap:Envelope> 
HTTP/1.1 401 Unauthorized 
Cache-Control: private 
Content-Type: text/html 
Server: Microsoft-IIS/7.5 
WWW-Authenticate: Basic realm="" 
X-AspNet-Version: 4.0.30319 
WWW-Authenticate: Basic realm="www.mywebsite.com" 
X-Powered-By: ASP.NET 
Date: Sun, 03 Jun 2012 07:14:40 GMT 
Content-Length: 1293 
------------------------------------------------------------------ 

POST http://www.mywebsite.com/Service1.asmx HTTP/1.1 
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.4927) 
VsDebuggerCausalityData: uIDPo+drc57U77xGu/ZaOdYvw6IAAAAA8AjKQNpkV06FEWDEs2Oja2C+h3kM7dlDvnFfE1VlIIIACQAA 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "http://www.mywebsite.com/HelloWorld" 
Authorization: Basic dXNlcjE6cEBzc3cwcmQ= 
Host: www.mywebsite.com 
Content-Length: 291 
Expect: 100-continue 

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><HelloWorld xmlns="http://www.mywebsite.com/" /></soap:Body></soap:Envelope> 
HTTP/1.1 401 Unauthorized 
Content-Type: text/html 
Server: Microsoft-IIS/7.5 
WWW-Authenticate: Basic realm="www.mywebsite.com" 
X-Powered-By: ASP.NET 
Date: Sun, 03 Jun 2012 07:14:41 GMT 
Content-Length: 1293 
------------------------------------------------------------------ 
+0

Asla kaçmadığından emin misiniz? Bunu onaylamak için bir kırılma noktası koydunuz mu? –

+0

Evet, eminim. Her zaman 'else' bloğu –

+0

çalıştırıyor. –

cevap

10

Rick Strahl's Blog dan senin özel HttpMo Buna dule kodu:

public class BasicAuthHttpModule : IHttpModule 
{ 
    public void Dispose() 
    { 
    } 

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

    public void OnAuthenticateRequest(object source, EventArgs 
         eventArgs) 
    { 
     HttpApplication app = (HttpApplication)source; 

     string authHeader = app.Request.Headers["Authorization"]; 
     if (!string.IsNullOrEmpty(authHeader)) 
     { 
      string authStr = app.Request.Headers["Authorization"]; 

      if (authStr == null || authStr.Length == 0) 
      { 
       return; 
      } 

      authStr = authStr.Trim(); 
      if (authStr.IndexOf("Basic", 0) != 0) 
      { 
       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]; 

      if (!MyUserValidator.Validate(username, password)) 
      { 
       DenyAccess(app); 
       return; 
      } 
     } 
     else 
     { 
      app.Response.StatusCode = 401; 
      app.Response.End(); 
     } 
    } 
    public void OnEndRequest(object source, EventArgs eventArgs) 
    { 
     if (HttpContext.Current.Response.StatusCode == 401) 
     { 
      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"; 
     app.Response.Write("401 Access Denied"); 
     app.CompleteRequest(); 
    } 
} 

Sonra Anonymous authentication etkinleştirmek ve IIS web siteniz için Basic, Digest ve Windows kimlik doğrulamasını devre dışı.

Not: Bu uygulama, WCF ile de çalışacaktır.

+0

Benim durumumda da Anonim kimlik doğrulamayı da devre dışı bırakmak zorunda kaldım. ' . ..' – Evilripper

+0

Benim için sadece klasik modda çalışmayan "Entegre uygulama havuzu modu" kullanan bir uygulama havuzunda çalışıyor. Ama neden tam olarak açıklayamıyorum ... – Lopo

+0

Benim için çalıştı ... web.config bölümünü düzenlemek zorunda kaldım. type = "BasicAuthHttpModule" türünde "AuthService.BasicAuthHttpModule, AuthService" türünü değiştirin. BasicAuthHttpModule'ın bir isim alanı içermediğini ekledim. –

1

Size ilk kez elle başlıkları göndermek istiyor gibi bir: Değiştir

string url = "http://rasnote/wconnect/admin/wc.wc?_maintain~ShowStatus"; 
    HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest; 

    string user = "ricks"; 
    string pwd = "secret"; 
    string domain = "www.west-wind.com"; 

    string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(user + ":" + pwd)); 
    req.PreAuthenticate = true; 
    req.Headers.Add("Authorization", auth); 
    req.UserAgent = ": Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 4.0.20506)"; 
    WebResponse resp = req.GetResponse(); 
    resp.Close(); 
+0

Bu kodu kullanıyorum ve aynı zamanda WebResponse resp = req.GetResponse(); –

+0

üzerinde kimlik doğrulama hatası veriyor Preauthenticate hakkında makalenin geri kalanını takip ettiniz mi? –