[英]Get bearer token from OWIN Cookie and put it on API Requests
這是我的情況:我有一個基於一個Thinktecture.IdentityServer提供商使用OpenIdConnectAuthentication一個MVC4.5 / WebApi2應用。 到目前為止,我可以對MVC進行身份驗證。 現在我想使用Bearer Token對WebApi進行身份驗證。 這是我的配置
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);
}
}
我甚至嘗試在app.UseWebApi(ConfigureAPI());
之后放置一個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);
}
}
那么,如何根據我的Owin Cookie中的訪問令牌為我的web api實現令牌認證?
提前致謝。
問題是IdentityServerBearerTokenAuthenticationOptions默認使用AuthenticationMode = ValidationMode.ValidationEndpoint;
默認情況下使用Microsoft.Owin.Security.AuthenticationMode.Active
並且無法覆蓋。
所以我將IdentityServerBearerTokenAuthenticationOptions設置為ValidationMode = ValidationMode.Local;
和AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive;
這很好,因為訪問令牌是一個JWT(自包含)。
我還使用OWIN中間件從請求中的cookie獲取訪問令牌,並將其設置在autorization標頭上。
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.