我試圖使用Thinktecture.IdentityModel中的ResourceAuthorize
屬性,但由於沒有owin上下文,所有內容都會停止。缺少owin上下文
我有設置授權管理器
[assembly: OwinStartup(typeof(My.WebApi.Startup))]
namespace My.WebApi
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
AuthConfig.Configure(app);
}
}
}
public class AuthConfig
{
public static void Configure(IAppBuilder app)
{
app.UseResourceAuthorization(new ResourceAuthorizationMiddlewareOptions
{
Manager = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IResourceAuthorizationManager)) as IResourceAuthorizationManager
});
}
}
一個owin啓動類,我知道它是檢測和調用。但後來,從IdentityModel
打下面的代碼時,我得到一個空指針異常:
public static Task<bool> CheckAccessAsync(this HttpRequestMessage request, IEnumerable<Claim> actions, IEnumerable<Claim> resources)
{
var authorizationContext = new ResourceAuthorizationContext(
request.GetOwinContext().Authentication.User ?? Principal.Anonymous,
actions,
resources);
return request.CheckAccessAsync(authorizationContext);
}
我已經通過加強並看到它是由GetOwinContext(引起的)返回null,因爲沒有MS_OwinContext
或MS_OwinEnvironment
財產的請求。
我錯過了什麼?
UPDATE:
我發現我有一個owin.environment
屬性可用,但它的`HttpContextWrapper,而不是請求的一部分。
通過圍繞搜索,我發現System.Web.Http.WebHost.HttpControllerHandler
看起來像它應該轉換的owin.environment
到MS_OwinEnvironment
,但顯然,該代碼永遠不會在我的情況下,所謂的內部一些代碼...
internal static readonly string OwinEnvironmentHttpContextKey = "owin.Environment";
internal static readonly string OwinEnvironmentKey = "MS_OwinEnvironment";
internal static HttpRequestMessage ConvertRequest(HttpContextBase httpContextBase, IHostBufferPolicySelector policySelector)
{
HttpRequestBase requestBase = httpContextBase.Request;
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethodHelper.GetHttpMethod(requestBase.HttpMethod), requestBase.Url);
bool bufferInput = policySelector == null || policySelector.UseBufferedInputStream((object) httpContextBase);
httpRequestMessage.Content = HttpControllerHandler.GetStreamContent(requestBase, bufferInput);
foreach (string str in (NameObjectCollectionBase) requestBase.Headers)
{
string[] values = requestBase.Headers.GetValues(str);
HttpControllerHandler.AddHeaderToHttpRequestMessage(httpRequestMessage, str, values);
}
HttpRequestMessageExtensions.SetHttpContext(httpRequestMessage, httpContextBase);
HttpRequestContext httpRequestContext = (HttpRequestContext) new WebHostHttpRequestContext(httpContextBase, requestBase, httpRequestMessage);
System.Net.Http.HttpRequestMessageExtensions.SetRequestContext(httpRequestMessage, httpRequestContext);
IDictionary items = httpContextBase.Items;
if (items != null && items.Contains((object) HttpControllerHandler.OwinEnvironmentHttpContextKey))
httpRequestMessage.Properties.Add(HttpControllerHandler.OwinEnvironmentKey, items[(object) HttpControllerHandler.OwinEnvironmentHttpContextKey]);
httpRequestMessage.Properties.Add(HttpPropertyKeys.RetrieveClientCertificateDelegateKey, (object) HttpControllerHandler._retrieveClientCertificate);
httpRequestMessage.Properties.Add(HttpPropertyKeys.IsLocalKey, (object) new Lazy<bool>((Func<bool>) (() => requestBase.IsLocal)));
httpRequestMessage.Properties.Add(HttpPropertyKeys.IncludeErrorDetailKey, (object) new Lazy<bool>((Func<bool>) (() => !httpContextBase.IsCustomErrorEnabled)));
return httpRequestMessage;
}
更新2:
在mvc控制器的內部,上下文是可用的。但不是在webapi控制器。
您可以安全地刪除global.asax文件,以便在應用程序中只獲取一個入口點。我不確定這是否會解決問題,但它肯定會讓事情變得更清潔...... – 2014-10-20 12:51:31
VS附帶的Web應用程序模板創建了global.asax和啓動類。有人說可以'保持',因爲它可以很容易地將事件掛鉤......我不確定它會幫助我刪除它,但會嘗試。 – Vegar 2014-10-20 16:45:23