4

我正在尝试使用Thinktecture.IdentityModelResourceAuthorize的属性,但由于没有 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
        });
    }
}

我知道它被检测到并被调用。但后来,当从 中点击以下代码时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_OwinContextorMS_OwinEnvironment属性。

我错过了什么?

更新:

我发现我有一个owin.environment可用的属性,但它是 `HttpContextWrapper 的一部分,而不是请求。

通过四处搜索,我发现其中的一些代码System.Web.Http.WebHost.HttpControllerHandler看起来应该已将 转换owin.environmentMS_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 控制器中。

4

1 回答 1

5

一个队友找到了解决办法。他只是在 owin 启动类中添加了以下行:

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

不过,为什么这能解决问题是另一个谜。但是我们正在使用 wsFederation,所以我想它需要一些方法。但是如果我们不使用 wsFed 会怎样?我们还需要它来获取上下文吗?谁知道...

于 2014-10-23T12:24:24.243 回答