Comment configurer mon projet mvc / webapi afin qu'une méthode webapi appelée à partir d'une vue rasoir ne renvoie pas la page de connexion lorsqu'elle n'est pas autorisée?
C'est une application MVC5 qui a également des contrôleurs WebApi pour les appels via javascript.
Les deux méthodes ci-dessous
[Route("api/home/LatestProblems")]
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
// Something here
}
[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
// Something there
}
sont appelés via le code angulaire suivant:
angular.module('appWorship').controller('latest',
['$scope', '$http', function ($scope,$http) {
var urlBase = baseurl + '/api/home/LatestProblems';
$http.get(urlBase).success(function (data) {
$scope.data = data;
}).error(function (data) {
console.log(data);
});
$http.get(baseurl + '/api/home/mylatestproblems')
.success(function (data) {
$scope.data2 = data;
}).error(function (data) {
console.log(data);
});
}]
);
Je ne suis donc pas connecté et la première méthode renvoie les données avec succès. la deuxième méthode renvoie (dans la fonction de succès) des données qui contiennent l'équivalent d'une page de connexion. c'est-à-dire ce que vous obtiendriez dans mvc si vous demandiez une action de contrôleur qui était estampillée avec [Authorize] et que vous n'étiez pas connecté.
Je veux qu'il renvoie un 401 non autorisé, afin que je puisse afficher différentes données pour les utilisateurs en fonction de s'ils sont connectés ou non. Idéalement, si l'utilisateur est connecté, je veux pouvoir accéder à la propriété Utilisateur du contrôleur afin de pouvoir renvoyer des données spécifiques à ce membre.
MISE À JOUR: Étant donné qu'aucune des suggestions ci-dessous ne semble plus fonctionner (changements dans Identity ou WebAPI), ive a créé un exemple brut sur github qui devrait illustrer le problème.
Brock Allen a un joli article de blog sur la façon de renvoyer 401 pour les appels ajax lors de l'utilisation de l'authentification Cookie et OWIN. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
Mettez ceci dans la méthode ConfigureAuth dans le fichier Startup.Auth.cs:
la source
/api
, vous pouvez utiliser le chemin pour déterminer s'il faut rediriger. C'est particulièrement utile si vous avez des clients qui utilisent d'autres formats comme JSON. Remplacez l'appel àIsAjaxRequest
parif (!context.Request.Path.StartsWithSegments(new PathString("/api")))
.private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
Si vous ajoutez asp.net WebApi à l'intérieur du site Web asp.net MVC, vous voudrez probablement répondre sans autorisation à certaines demandes. Mais alors l'infrastructure ASP.NET entre en jeu et lorsque vous essayez de définir le code d'état de réponse sur HttpStatusCode.Unauthorized, vous obtenez une redirection 302 vers la page de connexion.
Si vous utilisez l'identité asp.net et l'authentification basée sur owin, voici un code qui peut vous aider à résoudre ce problème:
la source
J'ai eu la même situation lorsque OWIN redirige toujours la réponse 401 vers la page de connexion de WebApi.Notre API Web prend en charge non seulement les appels ajax d'Angular mais aussi les appels Mobile, Win Form. Par conséquent, la solution pour vérifier si la requête est une requête ajax n'est pas vraiment triée pour notre cas.
J'ai opté pour une autre approche consiste à injecter une nouvelle réponse d'en-tête:
Suppress-Redirect
si les réponses proviennent de webApi. L'implémentation est sur le gestionnaire:Et enregistrez ce gestionnaire au niveau global de WebApi:
Ainsi, au démarrage d'OWIN, vous pouvez vérifier si l'en-tête de réponse a
Suppress-Redirect
:la source
Dans les versions précédentes d'ASP.NET, vous deviez faire tout un tas de choses pour que cela fonctionne.
La bonne nouvelle est que vous utilisez ASP.NET 4.5. vous pouvez désactiver la redirection d'authentification par formulaire à l'aide de la nouvelle propriété HttpResponse.SuppressFormsAuthenticationRedirect .
Dans
Global.asax
:EDIT : Vous voudrez peut-être également jeter un coup d'œil à cet article de Sergey Zwezdin qui présente une manière plus raffinée d'accomplir ce que vous essayez de faire.
Extraits de code pertinents et narration de l'auteur collés ci-dessous. Auteur original du code et de la narration - Sergey Zwezdin .
Tout d'abord, déterminons si la requête HTTP actuelle est une requête AJAX. Si oui, nous devrions désactiver le remplacement de HTTP 401 par HTTP 302:
Deuxièmement - ajoutons une condition :: si l'utilisateur est authentifié, alors nous enverrons HTTP 403; et HTTP 401 sinon.
Bien joué. Nous devons maintenant remplacer toutes les utilisations de AuthorizeAttribute standard par ce nouveau filtre. Cela ne s'applique peut-être pas aux gars sime, qui est esthète du code. Mais je ne connais pas d'autre moyen. Si c'est le cas, passons aux commentaires, s'il vous plaît.
Le dernier, ce que nous devrions faire - ajouter la gestion HTTP 401/403 côté client. Nous pouvons utiliser ajaxError à jQuery pour éviter la duplication de code:
Le résultat -
la source
Si vous exécutez votre à
Web API
partir de votreMVC
projet, vous devrez créer une personnalisationAuthorizeAttribute
à appliquer à vosAPI
méthodes. Dans le,IsAuthorized
override
vous devez saisir le courantHttpContext
pour empêcher la redirection, comme ceci:la source
En utilisant moi-même l'intégration d'Azure Active Directory, l'approche utilisant le
CookieAuthentication
middleware n'a pas fonctionné pour moi. J'ai dû faire ce qui suit:Si la requête provient du navigateur lui-même (et non d'un appel AJAX, par exemple), l'en-tête Accept contiendra la chaîne
html
quelque part. Ce n'est que lorsque le client accepte HTML que je considérerai une redirection comme quelque chose d'utile.Mon application cliente peut gérer le 401 informant l'utilisateur que l'application n'a plus accès et doit se recharger pour se reconnecter.
la source
J'avais également une application MVC5 (System.Web) avec WebApi (en utilisant OWIN) et je voulais simplement empêcher que 401 réponses de WebApi soient modifiées en 302 réponses.
Ce qui a fonctionné pour moi a été de créer une version personnalisée de WebApi AuthorizeAttribute comme ceci:
Et de l'utiliser à la place du standard WebApi AuthorizeAttribute. J'ai utilisé le MVC AuthorizeAttribute standard pour garder le comportement MVC inchangé.
la source
SuppressFormsAuthenticationRedirect
drapeau l'a obligé à renvoyer simplement le 401 existant pour moi.Installez simplement le package NeGet suivant
Package d'installation Microsoft.AspNet.WebApi.Owin
Écrivez le code suivant dans le fichier WebApiConfig.
la source
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
autrementUser.Identity.IsAuthenticated
toujoursfalse
si vous voulez attraper Content-Type == application / json, vous pouvez utiliser ce code:
Cordialement!!
la source
J'avais du mal à obtenir à la fois le code d'état et une réponse textuelle fonctionnant dans les méthodes OnAuthorization / HandleUnauthorizedRequest. Cela s'est avéré être la meilleure solution pour moi:
la source
Après avoir essayé d'éviter les redirections vers la page de connexion, j'ai réalisé que c'était en fait tout à fait approprié pour l'attribut Authorize. Il dit aller et obtenir l'autorisation. Au lieu des appels Api qui ne sont pas autorisés, je voulais juste ne révéler aucune information aux pirates informatiques. Cet objectif était plus facile à atteindre directement en ajoutant un nouvel attribut dérivé de Authorize qui masque à la place le contenu comme une erreur 404:
la source
En mélangeant MVC et WebAPI, si la demande n'est pas autorisée, elle sera également redirigée vers la page de connexion, même dans la demande WebAPI. Pour cela, nous pouvons ajouter ci-dessous le code pour envoyer une réponse à l'application mobile
la source
Merci les gars!
Dans mon cas, j'ai combiné les réponses de cuongle et Shiva , et j'ai obtenu quelque chose comme ceci:
Dans le gestionnaire OnException () du contrôleur pour les exceptions d'API:
Dans le code de configuration de démarrage de l'application:
la source
Dans MVC 5 avec Dot Net Framework 4.5.2, nous obtenons "application / json, texte de plainte .." sous l'en-tête "Accept" Ce sera agréable à utiliser comme suit:
la source