缺少欠上下文

时间:2014-10-20 12:23:31

标签: asp.net owin thinktecture-ident-model

我尝试使用Thinktecture.IdentityModel中的ResourceAuthorize属性,但由于没有欠上下文,所有内容都会停止。

我有一个设置授权管理器的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
        });
    }
}

我知道它已被检测并被调用。但是稍后,当从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_OwinContextMS_OwinEnvironment属性。

我错过了什么?

更新

我发现我有一个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控制器中。

1 个答案:

答案 0 :(得分:4)

队友找到了解决方案。他只是将以下行添加到owin启动类中:

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

为什么这个问题解决了另一个谜团。但我们正在使用wsFederation,所以我想它需要一些方法。但是如果我们不使用wsFed怎么办?我们还需要它来获取背景吗?谁知道......