2016-01-19 18 views
5

Ho un'API Web con autenticazione OWIN in Web MVC. Sto utilizzando <authentication> in Web.Config per il mio MVC Web, quindi sta reindirizzando la pagina di accesso.Effettuare l'autenticazione dell'API Web restituisce 401 anziché reindirizzare alla pagina di accesso

<authentication mode="Forms"> 
    <forms name="WEB.AUTH" loginUrl="~/login" domain="" protection="All" 
    timeout="43200" path="/" requireSSL="false" slidingExpiration="true" /> 
</authentication> 

sto usando attributo [System.Web.Http.Authorize] di autorizzare il mio Web API. Ma in qualche modo, l'API reindirizza alla pagina di accesso come la mia app MVC a causa della configurazione precedente.

quello che voglio fare è mantenere la funzione di reindirizzamento per il Web MVC ma restituendo 401 per Web API. Come posso raggiungere questo obiettivo? dovrei creare un attributo di autorizzazione personalizzato per l'API Web?

--EDIT--

ho trovato la risposta da questo post SuppressDefaultHostAuthentication in WebApi.Owin also suppressing authentication outside webapi

Così ho solo aggiungere alcune righe nel mio Startup.cs. Ho avuto tutti i miei controller configurati con un percorso di prefisso "api".

HttpConfiguration config = new HttpConfiguration(); 
//..some OWIN configuration 
app.Map("/api", inner => 
{ 
    inner.UseWebApi(config); 
}); 

assicuratevi di mettere app.Map() dopo le linee di configurazione Web API. Altrimenti, darà errore all'applicazione MVC.

risposta

1

Creare un costume AuthorizeAttribute:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) 
    { 
     actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized"); 
    } 
} 

Se in futuro saltare la roba web.config e utilizzare Owin per impostare l'autenticazione, si potrebbe in Startup.cs fare:

var provider = new CookieAuthenticationProvider(); 
var originalHandler = provider.OnApplyRedirect; 
provider.OnApplyRedirect = context => 
{ 
    if (!context.Request.Uri.LocalPath.StartsWith(VirtualPathUtility.ToAbsolute("~/api"))) 
    { 
     context.RedirectUri = new Uri(context.RedirectUri).PathAndQuery; 
     originalHandler.Invoke(context); 
    } 
}; 

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
    CookieName = FormsAuthentication.FormsCookieName, 
    LoginPath = new PathString("/Account/LogOn"), 
    ExpireTimeSpan = TimeSpan.FromMinutes(240), 
    Provider = provider 
}); 
+0

Non funziona per me. tuttavia, ho trovato la soluzione. Si prega di controllare il mio post modificato. – vantian

0

Questo è quello che ha funzionato per me.

Creazione di un attributo personalizzato:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class NoRedirectAuthorizeAttribute : AuthorizeAttribute 
{   
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext) 
    { 
     actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden); 
    } 
} 

Utilizzando l'attributo nel controller:

[HttpDelete] 
    [NoRedirectAuthorizeAttribute(Roles = "Admin")] 
    [Route("api/v3/thingstodelete/{id=id}")] 
    public IHttpActionResult DeleteThingToDelete(Guid id) 
    { 
     //delete code 
    } 

Qui ci sono solo l'override del metodo HandleUnauthorizedRequest del AuthorizeAttribute. Quindi, invece di inviare un reindirizzamento (304) alla pagina di accesso, inviamo il codice di stato HTTP Forbidden (403).