Sécurité et services Web
Cette section décrit les méthodes de sécurisation de vos services Web XML. Si vous n'avez pas encore lu la section Sécurité de ce didacticiel, faites-le avant de poursuivre cette rubrique.
Authentification et autorisation Windows
Pour sécuriser vos services Web XML à l'aide de l'authentification Windows, vous utilisez la même technique que pour les pages .aspx (voir la description à la section Authentification Windows). Pour exiger l'authentification, activez Authentification intégrée Windows pour votre application et désactivez Connexion anonyme dans la console de gestion de IIS. Pour autoriser ou refuser l'accès d'utilisateurs particuliers à votre service, utilisez le système de configuration ASP.NET ou définissez des ACL dans le fichier de service proprement dit, comme le montre l'exemple suivant :
<configuration>
<system.web>
<authentication mode="Windows"/>
</system.web>
<location path="secureservice.asmx">
<system.web>
<authorization>
<allow users="Administrator"/>
<allow users="DOMAIN\Bradley"/>
<deny roles="BUILTIN\Power Users"/>
</authorization>
</system.web>
</location>
</configuration>
Cette opération fonctionne correctement si vous êtes conscient que le client du service Web XML s'exécutera en tant qu'utilisateur Windows particulier. Il peut être intéressant d'examiner le cas d'un client s'exécutant en tant qu'utilisateur unique, mais agissant au nom d'un autre. Imaginons une page ASP.NET accédant à un service Web XML sécurisé qui n'emprunte pas l'identité du client qui y accède. Dans un tel cas, vous devez définir par programme le nom d'utilisateur et le mot de passe avant de vous connecter au service Web. L'exemple suivant utilise l'authentification de base et illustre un WebService simple :
<%@ WebService language="C#" Class="SecureService" %>
using System.Web.Services;
using System;
class SecureService : WebService {
[WebMethod]
public String SecureTest() {
return "Hello from the secure web service";
}
}
<%@ WebService language="VB" Class="SecureService" %>
Imports System.Web.Services
Imports System
Class SecureService : Inherits WebService
<WebMethod()> Public Function SecureTest As String
Return "Hello from the secure web service"
End
End Class
<%@ WebService language="JScript" Class="SecureService" %>
import System.Web.Services;
import System;
class SecureService extends WebService {
WebMethodAttribute function SecureTest() : String {
return "Hello from the secure web service";
}
}
|
|
C#
|
VB
|
JScript
|
|
Vous pouvez activer l'authentification de base pour ce service en définissant les paramètres appropriés dans IIS de la manière suivante :
- Ouvrez la console MMC IIS.
- Dans le volet gauche, développez l'arborescence pour rechercher votre répertoire virtuel.
- Dans le volet droit, cliquez avec le bouton droit sur Secureservice.asmx et choisissez Propriétés.
- Sélectionnez l'onglet Sécurité de fichier. Sous Connexions anonymes et contrôle d'authentification, cliquez sur Modifier.
- Désactivez l'accès anonyme.
- Désactivez l'authentification intégrée Windows.
- Activez l'authentification de base.
- Cliquez sur OK pour enregistrer ces paramètres et quittez la console MMC.
La classe proxy WebService de base propose deux propriétés, Username et Password, que vous pouvez utiliser pour spécifier les informations d'authentification avec lesquelles vous souhaitez vous connecter au service Web distant. Ces dernières doivent être définies comme informations d'authentification Windows valides sur l'ordinateur ou le domaine du service Web.
<%@ Import Namespace="SecureService" %>
<html>
<script language="C#" runat="server">
public void Page_Load (Object sender, EventArgs e) {
SecureService s = new SecureService();
s.Credentials = new System.Net.NetworkCredential ("Administrator", "test123");
Message.Text = s.SecureTest();
}
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
<%@ Import Namespace="SecureService" %>
<html>
<script language="VB" runat="server">
Public Sub Page_Load(sender As Object, e As EventArgs)
Dim s As New SecureService
s.Credentials = New System.Net. NetworkCredential ("Administrator", "test123")
Message.Text = s.SecureTest()
End Sub
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
<%@ Import Namespace="SecureService" %>
<html>
<script language="JScript" runat="server">
public function Page_Load (sender : Object, e : EventArgs) {
SecureService s = new SecureService();
s.Credentials = new System.Net.NetworkCredential ("Administrator", "test123");
Message.Text = s.SecureTest();
}
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
|
|
C#
|
VB
|
JScript
|
|
La classe WebService de base fournit une propriété User de type System.Security.Principal.IPrincipal, que vous pouvez utiliser pour extraire des informations à propos de l'utilisateur client. À nouveau, vous pouvez autoriser l'accès à votre service Web à l'aide de la section Authorization du système de configuration ASP.NET.
Authentification et autorisation personnalisées avec en-têtes Soap
L'authentification Windows est utile dans les scénarios intranet, dans lesquels vous authentifiez un utilisateur de votre propre domaine. Sur Internet, cependant, vous souhaiterez probablement personnaliser l'authentification et l'autorisation, éventuellement par rapport à une base de données SQL. Dans ce cas, passez des informations d'authentification personnalisées (telles que le nom d'utilisateur et le mot de passe) à votre service et laissez-le traiter lui-même l'authentification et l'autorisation.
Un en-tête SOAP offre un moyen pratique de passer des informations supplémentaires avec une demande à un service Web XML. Dans ce but, définissez une classe qui dérive de SOAPHeader dans votre service, puis déclarez un champ public de votre service comme possédant ce type. Cela est exposé dans le contrat public de votre service et mis à la disposition du client lorsque le proxy est créé à partir du fichier WebServiceUtil.exe, de la manière illustrée dans l'exemple suivant :
using System.Web.Services;
using System.Web.Services.Protocols;
// AuthHeader class extends from SoapHeader
public class AuthHeader : SoapHeader {
public string Username;
public string Password;
}
public class HeaderService : WebService {
public AuthHeader sHeader;
...
}
Imports System.Web.Services
Imports System.Web.Services.Protocols
' AuthHeader class extends from SoapHeader
Public Class AuthHeader : Inherits SoapHeader
Public Username As String
Public Password As String
End Class
Public Class HeaderService : Inherits WebService
Public sHeader As AuthHeader
...
End Class
import System.Web.Services;
import System.Web.Services.Protocols;
// AuthHeader class extends from SoapHeader
public class AuthHeader extends SoapHeader {
public var Username:String;
public var Password:String;
}
public class HeaderService extends WebService {
public var sHeader:AuthHeader;
...
}
|
|
C#
|
VB
|
JScript
|
|
Chaque WebMethod de votre service peut définir un ensemble d'en-têtes associés à l'aide de l'attribut personnalisé SoapHeader. Par défaut, l'en-tête est nécessaire, mais il est possible de définir également des en-têtes faciltatifs. L'attribut SoapHeader spécifie le nom d'un champ public ou d'une propriété de la classe Client ou Server (appelée propriété Headers dans cette rubrique). WebServices définit la valeur d'une propriété Headers avant que la méthode soit appelée pour les en-têtes d'entrée et récupère la valeur lorsque la méthode est retournée pour les en-têtes de sortie. Pour plus d'informations sur les en-têtes de sortie ou facultatifs, consultez la documentation du Kit de développement .NET Framework SDK.
[WebMethod(Description="This method requires a custom soap header set by the caller")]
[SoapHeader("sHeader")]
public string SecureMethod() {
if (sHeader == null)
return "ERROR: Please supply credentials";
else
return "USER: " + sHeader.Username;
}
<WebMethod(), SoapHeader("sHeader")> Public Function SecureMethod() As String
If (sHeader Is Nothing)
Return "ERROR: Please supply credentials"
Else
Return "USER: " & sHeader.Username
End If
End Function
WebMethodAttribute(Description="This method requires a custom soap header set by the caller")
SoapHeaderAttribute("sHeader")
public string SecureMethod() {
if (sHeader == null)
return "ERROR: Please supply credentials";
else
return "USER: " + sHeader.Username;
}
|
|
C#
|
VB
|
JScript
|
|
Un client définit ensuite l'en-tête sur la classe proxy juste avant le lancement d'un appel de méthode pour lequel il est nécessaire, comme le montre l'exemple suivant :
HeaderService h = new HeaderService();
AuthHeader myHeader = new AuthHeader();
myHeader.Username = "JohnDoe";
myHeader.Password = "password";
h.AuthHeader = myHeader;
String result = h.SecureMethod();
Dim h As New HeaderService
Dim myHeader As New AuthHeader
myHeader.Username = "JohnDoe"
myHeader.Password = "password"
h.AuthHeader = myHeader
Dim result As String = h.SecureMethod()
var h:HeaderService = new HeaderService();
var myHeader:AuthHeader = new AuthHeader();
myHeader.Username = "JohnDoe";
myHeader.Password = "password";
h.AuthHeader = myHeader;
var result:String = h.SecureMethod();
|
|
C#
|
VB
|
JScript
|
|
Pour voir ce code en action, exécutez l'exemple suivant :
- La sécurisation de vos services Web XML sur le serveur à l'aide de l'authentification Windows respecte exactement le même modèle que celui décrit pour la page .aspx.
- Vous pouvez également définir par programme les informations d'authentification Windows à l'aide des propriétés Username et Password de la classe proxy WebService.
- Enfin, vous pouvez effectuer une authentification personnalisée en passant des informations d'authentification sur les autorisations en tant que SOAPHeaders, ainsi qu'une demande SOAP pour la méthode qui l'exige.
|