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

相关问题