Jeton d’authentification et d’antiforgerie MVC avec modèle SPA Durandal

Certaines zones de mon SPA doivent être ouvertes à tous les utilisateurs et certaines nécessitent une authentification. Dans ces zones, ce sont les données chargées via AJAX que je souhaite protéger.

J’ai un service d’authentification (voir ci-dessous), que j’ajoute comme dépendance dans mon fichier principal.js Le service s’appelle:

authentication 

Dans mon main.js j’appelle

 authentication.handleUnauthorizedAjaxRequest(function () { app.showMessage('You are not authorized, please login') .then(function () { router.navigateTo('#/user/login'); }); }); 

Il avertit l’utilisateur qu’il n’est pas autorisé et navigue vers un modèle de vue / view de connexion où il peut entrer des détails et essayer de se connecter.

Quelques questions qui vous viennent à l’esprit lors de la construction de ce viewModel d’authentification:

  • Y at-il des préoccupations évidentes avec ce que je fais?
  • Est-ce que c’est comme ça que je «voulais» faire les choses à Durandal?
  • Est-ce que je réinvente la roue? Je ne pouvais rien voir de tel chez Durandal.

La plupart des gens semblent créer des pages cshtml distinctes; un pour la connexion (si l’utilisateur n’est pas authentifié) et l’ index habituel. index.cshtml Existe-t-il de bonnes raisons pour que je passe à cette méthode?

Mon action de connexion sur mon “contrôleur utilisateur” côté serveur a l’atsortingbut [ValidateAntiForgeryToken] que je dois également envoyer.
J’ai également un service ‘antiforgery’ (voir ci-dessous) que j’ajoute également comme dépendance dans mon fichier view.mod main.js (ainsi que dans mon main.js).

 antiforgery.addAntiForgeryTokenToAjaxRequests(); 

Cela intercepte toutes les requêtes ajax (avec le contenu) et ajoute la valeur de MVC AntiForgeryToken aux données. Semble fonctionner exactement comme je le veux. S’il vous plaît laissez-moi savoir s’il y a des erreurs / erreurs.

Service d’authentification complet ci-dessous.

 // services/authentication.js define(function (require) { var system = require('durandal/system'), app = require('durandal/app'), router = require('durandal/plugins/router'); return { handleUnauthorizedAjaxRequests: function (callback) { if (!callback) { return; } $(document).ajaxError(function (event, request, options) { if (request.status === 401) { callback(); } }); }, canLogin: function () { return true; }, login: function (userInfo, navigateToUrl) { if (!this.canLogin()) { return system.defer(function (dfd) { dfd.reject(); }).promise(); } var jqxhr = $.post("/user/login", userInfo) .done(function (data) { if (data.success == true) { if (!!navigateToUrl) { router.navigateTo(navigateToUrl); } else { return true; } } else { return data; } }) .fail(function (data) { return data; }); return jqxhr; } }; }); // services/antiforgery.js define(function (require) { var app = require('durandal/app'); return { /* this intercepts all ajax requests (with content) and adds the MVC AntiForgeryToken value to the data so that your controller actions with the [ValidateAntiForgeryToken] atsortingbute won't fail original idea came from http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken to use this 1) ensure that the following is added to your Durandal Index.cshml 
@Html.AntiForgeryToken()
2) in main.js ensure that this module is added as a dependency 3) in main.js add the following line antiforgery.addAntiForgeryTokenToAjaxRequests(); */ addAntiForgeryTokenToAjaxRequests: function () { var token = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(); if (!token) { app.showMessage('ERROR: Authentication Service could not find __RequestVerificationToken'); } var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(token); $(document).ajaxSend(function (event, request, options) { if (options.hasContent) { options.data = options.data ? [options.data, tokenParam].join("&") : tokenParam; } }); } }; });

Je préfère passer le jeton antiforgery dans l’en-tête. De cette façon, il est facile d’parsingr la requête sur le serveur car elle n’est pas mêlée aux données de votre formulaire.

J’ai ensuite créé un filtre d’action personnalisé pour rechercher le jeton antiforgery.

J’ai déjà créé un article sur la procédure à suivre.