RIA Services et Mix d’authentification Windows et Formulaire

Le but du jeu est de faire tourner une application Silverlight (v4) accompagnée de son site web ASP.Net et de ses services WCF Ria sur un réseau local avec authentification Windows. Jusque là rien de bien compliqué me diriez vous… SAUF que nous voulions profiter de la gestion de profils du membership ASP.Net (totalement standard et donc rien à développer, c’est pratique tout de même) et donc pour cela le plus simple est de faire une authentification par formulaire. De plus nous ne voulons évidement pas que les utilisateurs du réseau local aient à s’identifier dans un formulaire quelconque (ASP ou Silverlight) étant donné qu’ils l’ont déjà fait sur leur session Windows à leur arrivée au bureau…

Deux problèmes se posent donc :
– Mix du mode d’authentification (avec configuration de IIS 7.5 qui va bien)
– Récupération de l’utilisateur au niveau Silverlight pour ensuite utiliser le service d’authentification

1ere étape : Mixons les modes d’authentification

IIS ne supporte pas d’avoir le mode Windows et le mode Forms activé en même temps sur le même répertoire. Cependant dans la mesure où les services WCF générés par RIA sont accédés dans l’url http://monsite/CLIENTBIN/…..SVC  on peut très bien imaginer mettre la racine de notre site en mode d’authentification Windows, et convertir le sous dossier “ClientBin” en application (au sens IIS du terme) et activer le mode d’authentification par Formulaire sur ce sous dossier. Cependant cette solution à deux inconvénients dont un bloquant :

– Cela va nécessiter de dupliquer systématiquement le dossier “bin” contenant les dll de votre site web à la fois à la racine, et à la fois dans le dossier clientbin. C’est moche mais ça fonctionne.
– Cela ne fonctionnera pas pour les clients sous Internet Explorer (6, 7 ou 8)  + Windows XP ! En Effet, une sécurité (supprimée dans Windows 7 ? ) détecte un changement de mode d’authentification sur le même site (entre la racine et le sous dossier) et du coup le contenu des formulaires n’est plus envoyé. Y compris les requêtes POST générées par Silverlight quand il appelle les services WCF Ria ! Attention comme cela fonctionne sous Windows 7, vous pouvez penser que ça marche, mais ce n’est pas la bonne solution…

Donc vous l’avez compris, la solution consiste à passer le site en mode d’authentification par Formulaire dès la racine, car nous voulons absolument pouvoir utiliser ce mode sur nos appels depuis Silverlight. Comment utiliser l’authentification Windows alors ? Finalement ce qui nous intéresse c’est uniquement de récupérer le login Windows de l’utilisateur qui est en train d’arriver sur notre site. Ainsi on se servira de ce login, unique, pour communiquer avec l’API de membership via Silverlight. Nous allons donc réaliser la configuration suivante :

– Activer l’authentification par formulaire via le web.config de votre site par exemple.

<authentication mode="Forms">
<forms loginUrl="winlogin.aspx" />
</authentication>

– Ne pas autoriser les utilisateurs anonymes sur le site

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

– Utiliser une page aspx custom pour le login. En effet les anonymes n’étant pas autorisés, ils seront automatiquement redirigés sur cette page par votre config.

– Configurer IIS pour que le mode d’authentification Windows soit activé uniquement sur cette page de login. Pour cela sous IIS 7.5, il faut utiliser le bouton en bas de fenêtre ‘"Switch to Content View”, sélectionner la page winlogin.aspx, cliquer sur le bouton “Switch to Feature View”, et ensuite aller dans le choix du mode d’authentification. Cela permet de fixer cette configuration uniquement sur cette page.

– Dans le Page_Load de cette page, créer le cookie d’authentification par Formulaire comme si vous veniez de valider l’utilisateur et ensuite rediriger l’utilisateur sur la page contenant l’application Silverlight. A ce niveau dans le code, vous aurez une variable serveur disponible contenant le login de l’utilisateur: ServerVariables["LOGON_USER"]. En effet si le navigateur du client à bien détecté l’url du site comme un site “Intranet local”, il aura envoyé les crédentials de l’utilisateur automatiquement…

<%@ Page Language="C#" AutoEventWireup="true" %>
<script type="text/C#" runat="server">
   1:  

   2:  

   3: protected override void OnLoad(EventArgs e)

   4: {

   5:     FormsAuthentication.SetAuthCookie(HttpContext.Current.Request.ServerVariables["LOGON_USER"], true);

   6:     Response.Redirect("SLAppPage.aspx");

   7: }

</script>

Ainsi configuré, notre site va automatiquement “authentifier” les utilisateur du réseau local (Windows) dans un contexte d’authentification par formulaire.  De plus nous avons contourné le problème de sécurité de XP car les requêtes qui seront émises par notre application Silverlight se feront sur un mode d’authentification par formulaire, qui est le mode initial.

2nd étape : Utilisons ce login Windows dans notre Membership

La première chose à faire est de récupérer ce login et de le passer à l’application Silverlight. Pour celà le plus simple est d’utiliser le tag param dans votre balise object qui est chargé d’afficher le plugin Silverlight. En effet nous utilisons la mecan ique du initParam pour passer notre variable LOGON_USER à notre application SL :

– Côté aspx : 

<param name="initParams" value=’username= &lt;%= HttpContext.Current.Request.ServerVariables["LOGON_USER"] %&gt;' />

– Côté SL (dans App.xaml.cs, méthode Application_Startup) :

string userName = e.InitParams["username"];

De plus il faut avoir mis dans le constructeur de la classe App de quoi indiquer à Ria d’utiliser le mode d’authentification par Formulaire :

WebContext webContext = new WebContext();
webContext.Authentication = new FormsAuthentication();
this.ApplicationLifetimeObjects.Add(webContext);

Enfin notre choix a été de dire qu’étant donné que l’utilisateur a été préalablement authentifié par le réseau Windows, nous allions utiliser le même mot de passe pour tout les utilisateurs de l’application. Donc nous envoyons d’abord une tentative de login :

LoginOperation loginOperation = WebContext.Current.Authentication.Login(userName, “1234*Blah@”);

Enfin si lors du callback du login l’objet User retourné est null, cela signifie qu’il faut d’abord le créer dans la base de membership. Nous avons donc utilisé un service permettant d’appeler sur le serveur des méthodes de création de l’utilisateur. Ces méthodes sont exposée via RIA services. En interne elles utilisent l’API fournie par la classe MemberShip. Le tout étant configuré pour utiliser le Membership dans Sql Serveur, mais cela tiens plus de la configuration “standard” du Membership pour ASP.Net et donc je n’en parlerai pas plus.

Conclusion

Nous avons une application web qui utilisent les informations de login Windows pour créer à la volée et de manière transparente, des utilisateurs dans une base de donnée sql et permet ainsi à notre code Silverlight de stocker facilement des données de profils par utilisateurs sans que nous ayons eu à développer notre propre système de gestion utilisateurs et profils.

Source pour le mix d’authentification : http://msdn.microsoft.com/en-us/library/ms972958.aspx

Publié dans Silverlight Tagués avec : , , , , , , , , ,

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Verifions que vous êtes un humain * Time limit is exhausted. Please reload CAPTCHA.

Archives

Social

  • Twitter
  • LinkedIn
  • Flux RSS
  • mvp
  • technet
  • Google+