¿Cómo configuro mi proyecto mvc / webapi para que un método webapi llamado desde una vista de afeitar no devuelva la página de inicio de sesión cuando no está autorizado?
Es una aplicación MVC5 que también tiene controladores WebApi para llamadas a través de javascript.
Los dos métodos a continuación
[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
}
se llaman a través del siguiente código angular:
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);
});
}]
);
Así que no he iniciado sesión y el primer método devuelve datos con éxito. el segundo método devuelve (en la función de éxito) datos que contienen el equivalente de una página de inicio de sesión. es decir, lo que obtendrías en mvc si solicitaras una acción de controlador que estuviera sellada con [Autorizar] y no estuvieras conectado.
Quiero que devuelva un 401 no autorizado, para que pueda mostrar diferentes datos para los usuarios en función de si están conectados o no. Idealmente, si el usuario ha iniciado sesión, quiero poder acceder a la propiedad de Usuario del Controlador para poder devolver datos específicos de ese Miembro.
ACTUALIZACIÓN: Dado que ninguna de las sugerencias a continuación parecen funcionar (cambios en Identity o WebAPI) he creado un ejemplo en bruto en github que debería ilustrar el problema.
Brock Allen tiene una buena publicación de blog sobre cómo devolver 401 para llamadas ajax cuando se utiliza la autenticación de cookies y OWIN. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
Ponga esto en el método ConfigureAuth en el archivo Startup.Auth.cs:
fuente
/api
, puede usar la ruta para determinar si se debe redirigir. Es especialmente útil si tiene clientes que usan otros formatos como JSON. Reemplace la llamada aIsAjaxRequest
conif (!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 está agregando asp.net WebApi dentro del sitio web asp.net MVC, probablemente desee responder sin autorización a algunas solicitudes. Pero luego entra en juego la infraestructura ASP.NET y cuando intentas configurar el código de estado de respuesta en HttpStatusCode. Sin autorización, obtendrás una redirección 302 a la página de inicio de sesión.
Si está utilizando la identidad asp.net y la autenticación basada en Owin aquí, un código que puede ayudar a resolver ese problema:
fuente
Tuve la misma situación cuando OWIN siempre redirige la respuesta 401 a la página de inicio de sesión de WebApi. Nuestra API web no solo admite llamadas ajax desde Angular, sino también llamadas de formulario Win móvil. Por lo tanto, la solución para verificar si la solicitud es ajax no está realmente ordenada para nuestro caso.
He optado por otro enfoque es inyectar una nueva respuesta de encabezado:
Suppress-Redirect
si las respuestas provienen de webApi. La implementación está en el controlador:Y registre este controlador en el nivel global de WebApi:
Entonces, en el inicio de OWIN puede verificar si el encabezado de respuesta tiene
Suppress-Redirect
:fuente
En versiones anteriores de ASP.NET, tenía que hacer un montón de cosas para que esto funcionara.
La buena noticia es que está usando ASP.NET 4.5. puede deshabilitar la redirección de autenticación de formularios utilizando la nueva propiedad HttpResponse.SuppressFormsAuthenticationRedirect .
En
Global.asax
:EDITAR : También es posible que desee echar un vistazo a este artículo de Sergey Zwezdin que tiene una forma más refinada de lograr lo que está tratando de hacer.
Fragmentos de código relevantes y narración del autor pegados a continuación. Autor original del código y la narración - Sergey Zwezdin .
Primero, determinemos si la solicitud HTTP actual es una solicitud AJAX. En caso afirmativo, debemos deshabilitar el reemplazo de HTTP 401 con HTTP 302:
Segundo: agreguemos una condición :: si el usuario está autenticado, entonces enviaremos HTTP 403; y HTTP 401 de lo contrario.
Bien hecho. Ahora deberíamos reemplazar todos los usos de AuthorizeAttribute estándar con este nuevo filtro. Es posible que no sea aplicable para los chicos de Sime, que es el esteta del código. Pero no sé de otra manera. Si es así, vamos a los comentarios, por favor.
Lo último, lo que debemos hacer: agregar el manejo de HTTP 401/403 en el lado del cliente. Podemos usar ajaxError en jQuery para evitar la duplicación de código:
El resultado -
fuente
Si está ejecutando su
Web API
desde suMVC
proyecto, deberá crear una costumbreAuthorizeAttribute
para aplicar a susAPI
métodos. Dentro de loIsAuthorized
override
que necesita para tomar la corrienteHttpContext
para evitar la redirección, así:fuente
Usando yo mismo la integración de Azure Active Directory, el enfoque usando el
CookieAuthentication
middleware no funcionó para mí. Tuve que hacer lo siguiente:Si la solicitud proviene del navegador en sí (y no de una llamada AJAX, por ejemplo), el encabezado Aceptar contendrá la cadena
html
en alguna parte. Solo cuando el cliente acepte HTML consideraré una redirección algo útil.Mi aplicación cliente puede manejar el 401 informando al usuario que la aplicación no tiene más acceso y necesita volver a cargar para iniciar sesión nuevamente.
fuente
También tenía una aplicación MVC5 (System.Web) con WebApi (usando OWIN) y solo quería evitar que 401 respuestas de WebApi se cambiaran a 302 respuestas.
Lo que funcionó para mí fue crear una versión personalizada de WebApi AuthorizeAttribute como esta:
Y para usarlo en lugar del estándar WebApi AuthorizeAttribute. Usé el MVC AuthorizeAttribute estándar para mantener el comportamiento de MVC sin cambios.
fuente
SuppressFormsAuthenticationRedirect
bandera, me devolvió el 401 existente.Simplemente instale el siguiente paquete NeGet
Paquete de instalación Microsoft.AspNet.WebApi.Owin
Escriba el siguiente código en el archivo WebApiConfig.
fuente
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
de otra formaUser.Identity.IsAuthenticated
es siemprefalse
si desea capturar Content-Type == application / json puede usar ese código:
¡¡Saludos!!
fuente
Estaba teniendo dificultades para conseguir que tanto el código de estado como la respuesta de texto funcionaran en los métodos OnAuthorization / HandleUnauthorizedRequest. Esta resultó ser la mejor solución para mí:
fuente
Después de mucho alboroto tratando de evitar las redirecciones a la página de inicio de sesión, me di cuenta de que esto es realmente muy apropiado para el atributo Autorizar. Está diciendo ir y obtener autorización. En cambio, para las llamadas Api que no están autorizadas, solo quería no revelar ninguna información a los piratas informáticos. Este objetivo fue más fácil de lograr directamente al agregar un nuevo atributo derivado de Autorizar que en su lugar oculta el contenido como un error 404:
fuente
Mezclando MVC y WebAPI, si la solicitud no está autorizada, se redirigirá a la página de inicio de sesión incluso en la solicitud de WebAPI también. Para eso, podemos agregar el siguiente código para enviar una respuesta a la aplicación móvil
fuente
¡Gracias chicos!
En mi caso, combiné las respuestas de cuongle y Shiva , y obtuve algo como esto:
En el controlador OnException () del controlador para excepciones de API:
En el código de configuración de inicio de la aplicación:
fuente
En MVC 5 con Dot Net Framework 4.5.2 estamos obteniendo "application / json, texto simple .." bajo el encabezado "Aceptar" Será bueno usarlo de la siguiente manera:
fuente