2013-07-07 21 views
6

Desidero utilizzare i servizi Web con Ajax. Qual è il modo migliore per la sicurezza quando si chiama webservice usando ajax? Voglio proteggermi dalla chiamata remota fuori dall'applicazione.Asp.net Webservice - Chiamata sicura al servizio web con jquery AJAX

Ho il seguente webservice ad esempio:

[WebService(Namespace = "http://tempuri.org/")] 
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [System.ComponentModel.ToolboxItem(false)] 
    [System.Web.Script.Services.ScriptService] 
    public class Users : System.Web.Services.WebService 
    { 

     [WebMethod] 
     public List<User> GetUsers() 
     { 
      List<User> listUsers = new List<User>(); 
      User user = new User(); 
      user.Id = 1; 
      user.Name = "John"; 

      User user2 = new User(); 
      user2.Id = 2; 
      user2.Name = "Martin"; 


      listUsers.Add(user); 
      listUsers.Add(user2); 

      return listUsers; 
     } 
    } 
} 

io chiamo il webservice con jquery ajax:

<script type="text/javascript"> 
    $(function() { 

     getUsers(); 


     function getUsers() { 

      $.ajax({ 
       type: "POST", 

       url: "Webservices/Users.asmx/GetUsers", 

       data: "{}", 

       contentType: "application/json; charset=utf-8", 

       dataType: "json", 

       success: function (response) { 

        var users = response.d; 

        $.each(users, function (index, user) { 

         console.log(user.Name); 

        }); 

       }, 

       failure: function (msg) { 
       } 
      }); 
     } 
    }); 
</script> 
+0

dato quello che è l'applicazione che chiama il servizio web? ASP.NET Web Forms, MVC? La parte .asmx della stessa applicazione è? In che modo è garantita l'applicazione web che chiama .asmx? Stai usando l'autenticazione basata su form per questo? – Badri

+0

@Badri - Grazie per le vostre domande. Uso i Web Form ASP.NET. L'asmx è nella stessa applicazione. Faccio una domanda di chat e voglio usare un webservice per salvare il messaggio e recuperare il nuovo messaggio. Voglio fare un webservice sicuro per l'invio di messaggi in chat. La chat può utilizzare solo l'utente registrato. Per l'autenticazione voglio utilizzare l'autenticazione della forma. – Jenan

risposta

9

Non esiste una cosa come il modo migliore e la risposta è sempre it depends, anche se è molto utile. Ad esempio, è possibile utilizzare forms authentication. Se l'applicazione Web che utilizza il servizio Web e il servizio Web fanno parte dello stesso ASP.NET application, il browser può inviare senza problemi il ticket di autenticazione dei moduli (cookie) per ogni chiamata al servizio web.

Nel file di configurazione, è possibile avere

<authorization> 
     <deny users="?" /> 
</authorization> 

Ciò negare l'accesso agli utenti anonimi e che coprirà i servizi web come bene. In altre parole, a meno che un utente non acceda e ottenga un cookie valido con il ticket, il servizio non può essere utilizzato. Certo, devi HTTPS. Altrimenti, chiunque nel mezzo può ottenere il cookie nelle intestazioni e chiamare il servizio.

Infine, non è possibile garantire che nessuno chiami il servizio Web al di fuori dell'applicazione in senso assoluto. L'approccio sopra riportato garantisce che nessuno nel mezzo chiami il tuo servizio. Ma non c'è modo di garantire che un utente valido chiami il servizio direttamente al di fuori dell'applicazione perché il chiamante del servizio web è JavaScript e qualsiasi sicurezza che si crea in JavaScript può essere facilmente individuata da un utente guardando lo script o anche guardando il traffico da e verso il browser. Qualsiasi utente finale che è un po 'tecnico, sarà in grado di riprodurre le richieste o modificare le richieste e inviare al servizio web utilizzando credenziali valide.

EDIT: -

Ecco i dettagli che stai cercando per consentire FormsAuthentication.

(1) In Web.config, sotto <system.web>, assicurarsi di avere questo.

<authentication mode="Forms"> 
    <forms loginUrl="Login.aspx" defaultUrl="~/" /> 
</authentication> 
<authorization> 
    <deny users="?" /> 
</authorization> 

Ciò garantirà che tutti gli utenti non autenticati (anonimi) vengano reindirizzati a Login.aspx.

(2) Implementare Login.aspx con la logica di accesso per ottenere l'ID utente e la password e convalidarli su un database o qualsiasi altra cosa. Una volta che l'autenticazione ha avuto successo, cioè l'ID immesso dall'utente e la password corrispondono a ciò che si ha nel database, potrebbero essere nel gestore di clic del pulsante di accesso, impostare il ticket.

protected void Button1_Click(object sender, EventArgs e) 
{ 
    // Do all your login logic here 
    // once user ID and password entered by the user are okay, call this 

    string ticket = FormsAuthentication.Encrypt(
         new FormsAuthenticationTicket("userId", false, 15)); 
    HttpCookie FormsCookie = new HttpCookie(
       FormsAuthentication.FormsCookieName, ticket) { HttpOnly = true }; 
    HttpContext.Current.Response.Cookies.Add(FormsCookie); 
} 

(3) Aggiungere PrincipalPermissionAttribute al metodo web come questo.

public class Users : System.Web.Services.WebService 
{ 
    [PrincipalPermissionAttribute(SecurityAction.Demand)] 
    [WebMethod] 
    public List<User> GetUsers() 
    { 
     // Same code as what you have now 
    } 
} 

Se ora si va in qualsiasi pagina, sarete reindirizzati al Login.aspx dove sarà necessario immettere l'ID utente e la password e login. Al momento dell'accesso, il cookie di autenticazione dei moduli verrà creato e scritto nella risposta.Da quel momento in poi, tutte le richieste alla tua applicazione introdurranno il cookie (il browser lo farà per te). Senza accedere, se si accede direttamente al servizio Web, verrà comunque reindirizzato alla pagina di accesso. Come ho accennato nella mia risposta originale, un utente che ha effettuato l'accesso sarà comunque in grado di accedere direttamente al servizio web. Se JavaScript può fare qualcosa, un utente può fare lo stesso.

BTW, i servizi Web (asmx) sono una tecnologia obsoleta.

+0

Che tipo è ora utilizzato al posto di asmx? – Jenan

+0

Grazie mille per il tuo ottimo promemoria: "i servizi web (asmx) sono una tecnologia deprecata". Io uso il servizio WCF. Puoi modificare la risposta per l'utilizzo del servizio wcf? Grazie. – Jenan

+0

La mia risposta sarà la stessa anche per la WCF. Per pt. 3, anziché applicare '[PrincipalPermissionAttribute (SecurityAction.Domanda)] 'sul metodo web, applicare lo stesso nel metodo della classe che implementa il contratto di servizio WCF. Invece di WCF, se si prevede di utilizzare l'API Web ASP.NET, che è un f/w per creare servizi HTTP, anche allora lo stesso approccio funzionerà. L'API Web fornisce un attributo 'Authorize' che è possibile utilizzare al posto di' PrincipalPermission', ma fondamentalmente si tratta di verificare in modo dichiarativo se esiste un'identità autenticata associata al principal corrente. – Badri

1

Una cosa che puoi fare per prevenire chiamate fuori dal browser consiste nel mettere un token monouso nella tua pagina quando lo costruisci, quindi pubblicarlo durante la tua chiamata AJAX. Una semplice implementazione sarebbe una tabella di database con una serie di valori casuali (forse 32-alfanumerici o simili). Quando costruisci la pagina, recupera uno dei valori dalla tabella e inseriscilo nella tua pagina - quando crei il tuo modulo AJAX, includi quel valore.

Sul lato server, assicurarsi che il valore esista nella tabella, quindi eliminarlo dalla tabella.

Se il servizio viene chiamato di nuovo con quel valore, fallirà perché il valore non è più nella tabella.

Ciò significa che per generare un token valido, è necessario prima ottenere la pagina e quindi è possibile utilizzare quel token solo una volta.

È possibile inserire ulteriori controlli come indirizzo IP, agente utente, valori dei cookie, date di scadenza, ecc. E fare cose come i valori di hashing con una chiave segreta o altri metodi di sicurezza per oscurità.

Alla fine però, come indica Badri, tutto questo può essere falsificato se qualcuno lo desidera, semplicemente creando manualmente la richiesta HTTP che il browser stava per effettuare per la chiamata AJAX. Il meglio che puoi fare è assicurarti che solo gli utenti validi possano chiamare il servizio (indipendentemente dalla tecnologia client che stanno utilizzando), e ciò viene realizzato attraverso l'autenticazione basata su formulari tradizionali.

2

Questo è un argomento molto importante per la discussione. Ci possono essere molti modi per farlo.

Utilizziamo personalmente Service Stack per API e usiamo una chiave quando accediamo all'API. Key è un guid che rimane lo stesso per Client e Server. Se Client e server sono lo stesso sistema, non ci saranno problemi con la pubblicazione di una chiave.

A modi molto dettagliate per sicuro è qui http://www.stormpath.com/blog/secure-your-rest-api-right-way http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/

Anche per ulteriore esempio Building Secure Public API with PHP/MYSQL

Problemi correlati