3

這裏是我的情況:我 有根據Thinktecture.IdentityServer提供商使用OpenIdConnectAuthentication一個MVC4.5/WebApi2應用。到目前爲止,我可以對MVC進行身份驗證。現在我想用Bearer Token對WebApi進行身份驗證。下面是我的配置從OWIN的Cookie獲取承載令牌,並把它放在API請求

app.UseWebApi(ConfigureAPI()); 
app.UseCookieAuthentication(new CookieAuthenticationOptions() { 
     AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, 
     CookieSecure = CookieSecureOption.Always, 
     AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active, 
     CookieHttpOnly = true 
    }); 

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions() { 
       EnableValidationResultCache = false, 
       Authority = WebConfigurationManager.AppSettings["Authority"], 
       AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive 
      }); 

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() { 
       Authority = WebConfigurationManager.AppSettings["Authority"], 
       ClientId = WebConfigurationManager.AppSettings["ClientId"], 
       ClientSecret = WebConfigurationManager.AppSettings["ClientSecret"], 
       ResponseType = "code id_token", 
       Scope = "openid email profile", 
       SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType, 
       Notifications = new OpenIdConnectAuthenticationNotifications { 
        AuthenticationFailed = OnAuthenticationFailed, 
        AuthorizationCodeReceived = OnAuthorizationCodeReceived, 
        RedirectToIdentityProvider = OnRedirectToIdentityProvider 
       } 
      }; 
); 

而且我的WebAPI配置

public HttpConfiguration ConfigureAPI() { 
      var httpConfig = new HttpConfiguration(); 
      // Configure Web API to use only bearer token authentication. 
      httpConfig.SuppressDefaultHostAuthentication(); 
      httpConfig.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));  
      httpConfig.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

      // Web API routes 
      httpConfig.MapHttpAttributeRoutes(); 

      httpConfig.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{controller}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 
      return httpConfig; 
     } 

因爲我已經在我的OWIN Cookie的訪問令牌,我想將它添加到授權頭到達API等前獲得成功的身份驗證。

這裏是我試過

public class CustomAuthorizeAttribute : AuthorizeAttribute { 
     protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) { 
      var cookies = actionContext.Request.Headers.GetCookies(".AspNet.Cookies"); 
      var cookie = cookies.First().Cookies.FirstOrDefault(c => c.Name == ".AspNet.Cookies"); 
      if (cookie != null) {    
       var unprotectedTicket = Startup.OAuthOptions.TicketDataFormat.Unprotect(ticket); 
       actionContext.Request.Headers.Add("Authorization", string.Format("Bearer {0}", unprotectedTicket.Identity.Claims.First(c => c.Type == "access_token").Value));     
      } 
      return base.IsAuthorized(actionContext); 
     } 
    } 

我甚至嘗試用OWIN中間件放置app.UseWebApi(ConfigureAPI());

public class UseCookieToBearerAuthentication : OwinMiddleware { 
     public UseCookieToBearerAuthentication(OwinMiddleware next) : base(next) { } 

     public async override Task Invoke(IOwinContext context) { 
      //TODO Retrieve cookie name from somewhere like in FormsAuthentication.FormsCookieName   
      var cookies = context.Request.Cookies; 
      var cookie = cookies.FirstOrDefault(c => c.Key == ".AspNet.Cookies"); 
      if (!cookie.Equals(default(KeyValuePair<string, string>))) { 
       var ticket = cookie.Value; 
       var unprotectedTicket = Startup.OAuthOptions.TicketDataFormat.Unprotect(ticket); 
       context.Request.Headers.Add("Authorization", new string[]{ 
        string.Format("Bearer {0}", unprotectedTicket.Identity.Claims.First(c => c.Type == "access_token").Value) 
       }); 
      } 
      await Next.Invoke(context); 
     } 
    } 

所以後,我如何能實現令牌認證爲我的網頁API基於訪問令牌在我的歐文餅乾?

在此先感謝。

回答

0

的問題是,IdentityServerBearerTokenAuthenticationOptions默認使用AuthenticationMode = ValidationMode.ValidationEndpoint;,默認情況下使用Microsoft.Owin.Security.AuthenticationMode.Active,並且不能被重寫。

所以我設置IdentityServerBearerTokenAuthenticationOptionsValidationMode = ValidationMode.Local;AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive;這是很好的,因爲訪問令牌是智威湯遜(自足)。

我還使用OWIN中間件從請求中的cookie獲取訪問令牌並將其設置在自動化標頭上。

public class UseCookieToBearerAuthentication : OwinMiddleware { 
     public UseCookieToBearerAuthentication(OwinMiddleware next) : base(next) { } 



    public async override Task Invoke(IOwinContext context) { 
       var x = Startup.OAuthOptions.CookieName; 
       var cookieName = string.Format("{0}{1}", CookieAuthenticationDefaults.CookiePrefix, CookieAuthenticationDefaults.AuthenticationType); 
       var cookies = context.Request.Cookies; 
       var cookie = cookies.FirstOrDefault(c => c.Key == ".AspNet.Cookies"); 
       if (!cookie.Equals(default(KeyValuePair<string, string>))) { 
        var ticket = cookie.Value; 
        var unprotectedTicket = Startup.OAuthOptions.TicketDataFormat.Unprotect(ticket); 
        context.Request.Headers.Add("Authorization", new string[]{ 
         string.Format("Bearer {0}", unprotectedTicket.Identity.Claims.First(c => c.Type == "access_token").Value) 
        }); 
       } 
       await Next.Invoke(context); 
      } 
     } 
+3

我們實際上想擺脫Web API的Cookie - 這是一種反模式,容易受到CSRF攻擊。如果您絕對想要使用cookie,那麼在Web API中使用cookie中間件 - 否則不要使用cookie並通過顯式驗證正確執行 - http://leastprivilege.com/2015/04/01/implicit-vs-基於明確的身份驗證,在瀏覽器的應用程序/ – leastprivilege

相關問題