Bonjour/Bonsoir,

Je viens de passer plusieurs jours à suivre différents tutoriels plus ou moins complets à propos du moyen d'authentifier les accès au service WCF en utilisant les utilisateurs et les roles ASP.NET.

Malheureusement je n'arrive pas à faire fonctionner la dite authentification. Je sais que je suis pas loin mais il n'y a rien à faire ca veux pas.

Je sollicite donc votre aide pour trouver ce que j'ai raté dans ma configuration ou dans mon code.

Je travaille sur un Vista avec VS2008, mon service est hebergé sur le IIS7 de ma machine. Le code du client est généré par VS.

Voici une capture de l'outil d'admin IIS:


Mon web.config est le suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <clear/>
	  <add name="LocalSqlServer" connectionString="Data Source=KWISATZ\SQLEXPRESS;Initial Catalog=aspnetdb;Integrated Security=True"/>
	</connectionStrings>
  <system.web>
    <membership defaultProvider="SqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear/>
        <add
          name="SqlMembershipProvider"
          type="System.Web.Security.SqlMembershipProvider"
          connectionStringName="LocalSqlServer"
          applicationName="MembershipAndRoleProviderSample"
          enablePasswordRetrieval="false"
          enablePasswordReset="false"
          requiresQuestionAndAnswer="false"
          requiresUniqueEmail="true"
          passwordFormat="Hashed" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="SqlRoleProvider">
      <providers>
        <clear/>
        <add name="SqlRoleProvider"
             type="System.Web.Security.SqlRoleProvider"
             connectionStringName="LocalSqlServer"
             applicationName="MembershipAndRoleProviderSample"/>
      </providers>
    </roleManager>
		<compilation debug="true">
			<assemblies>
				<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
				<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</assemblies>
		</compilation>
 
    <authentication mode="Forms" />
 
	</system.web>
 
  <system.codedom>
		<compilers>
			<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
				<providerOption name="CompilerVersion" value="v3.5"/>
				<providerOption name="WarnAsError" value="false"/>
			</compiler>
		</compilers>
	</system.codedom>
 
  <!--system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
		<modules>
			<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</modules>
		<handlers>
			<remove name="WebServiceHandlerFactory-Integrated"/>
			<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</handlers>
	</system.webServer-->
	<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="MyServiceBinding">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="MyService.Service1Behavior" name="MyService.MyService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="" contract="MyService.IMyService">
          <!--<identity><dns value="localhost" /></identity>-->
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyService.Service1Behavior">
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlMembershipProvider" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
	</system.serviceModel>
</configuration>
Le contrat du service est le suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace MyService
{
    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        String HelloAdmin();
 
        [OperationContract]
        String HelloContrib();
 
        [OperationContract]
        String HelloAll();
    }
}
Voici la classe implémentant ce contrat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
namespace MyService
{
    public class MyService : IMyService
    {
        [PrincipalPermission(SecurityAction.Demand, Role = "administrateur")]
        public string HelloAdmin()
        {
            return "Hello Admins";
        }
 
        [PrincipalPermission(SecurityAction.Demand, Role = "contributeur")]
        public string HelloContrib()
        {
            return "Hello Contribs";
        }
 
        [PrincipalPermission(SecurityAction.Demand)]
        public string HelloAll()
        {
            var identity = ServiceSecurityContext.Current.PrimaryIdentity;
            return "Hi All";
        }
    }
}
Dans le snippet ci-dessus vous pouvez voir un "var identity". La valeur de cet variable n'est jamais correcte.

Maintenant voici le client qui utilise un user existant de la base de donnée ASP.NET :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
namespace WCFServiceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var service = new MyServiceClient();
                service.ClientCredentials.UserName.UserName = "plop";
                service.ClientCredentials.UserName.Password = "42plop_42";
 
                Console.WriteLine(service.HelloAll());
                Console.WriteLine(service.HelloAdmin());
                //Console.WriteLine(service.HelloContrib());
            }
            catch (SecurityAccessDeniedException e)
            {
                Console.WriteLine("Acces Interdit : {0}", e.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
Dans le client de test l'appel à HelloAdmin lance une exception car l'authentification n'as pas lieu. L'appel à HelloAll lui fonctionne mais comme dit ci-dessus l'identité récupéré n'est pas correcte, c'est une identité de type Windows à la place d'une identité ASP.NET.

Merci des pistes, solution et/ou de l'aide que vous pourrez m'apporter.