Asp.net web api 使用IdentityServer和Autofac-can'保护webapi;我得不到索赔

Asp.net web api 使用IdentityServer和Autofac-can'保护webapi;我得不到索赔,asp.net-web-api,owin,autofac,identityserver3,Asp.net Web Api,Owin,Autofac,Identityserver3,我正试图用IdentityServer和OpenID Connect使用Autofac保护我的webapi。我用的是OWIN。但由于某些原因,我无法获得用户的索赔。似乎根本没有触发AccessTokenValidation。这让我觉得我在创业时的声明顺序有问题。这是我的创业公司 public class Startup { public void Configuration(IAppBuilder appBuilder) { // Add authentication

我正试图用IdentityServer和OpenID Connect使用Autofac保护我的webapi。我用的是OWIN。但由于某些原因,我无法获得用户的索赔。似乎根本没有触发AccessTokenValidation。这让我觉得我在创业时的声明顺序有问题。这是我的创业公司

public class Startup {

    public void Configuration(IAppBuilder appBuilder) {

        // Add authentication
        this.AddAuthentication(appBuilder);

        HttpConfiguration config = new HttpConfiguration();
        var container = CreateAutofacContainer();

        var resolver = new AutofacWebApiDependencyResolver(container);
        config.DependencyResolver = resolver;  
        WebApiConfig.Register(config);
        config.EnsureInitialized();

        // Register config - you can't add anything to pipeline after this
        appBuilder.UseAutofacMiddleware(container);
        appBuilder.UseAutofacWebApi(config);
        appBuilder.UseWebApi(config);       
    }

    private static IContainer CreateAutofacContainer() {

        var autofacBuilder = new ContainerBuilder();

        var assembly = Assembly.GetExecutingAssembly();

        // Register your Web API controllers.
        autofacBuilder.RegisterApiControllers(assembly);

        // For general logging implementation
        autofacBuilder.RegisterType<ConsoleLogger>().As<ILogger>();

        // Create empty usage context to be filled in OWIN pipeline
        IUsageContext usageContext = new RuntimeUsageContext();
        autofacBuilder.RegisterInstance(usageContext).As<IUsageContext>().SingleInstance();

        // We need to get usage context builded
        autofacBuilder.RegisterType<OIDCUsageContextProvider>().InstancePerRequest();

        var container = autofacBuilder.Build();
        return container;
    }

    private void AddAuthentication(IAppBuilder app) {

        var options = new IdentityServerBearerTokenAuthenticationOptions();

        options.Authority = "MYAUTHORITY";
        options.RequiredScopes = new[] { "openid", "profile", "email", "api" };
        options.ValidationMode = ValidationMode.ValidationEndpoint;
        app.UseIdentityServerBearerTokenAuthentication(options);

        // Add local claims if needed
        app.UseClaimsTransformation(incoming => {

            // either add claims to incoming, or create new principal
            var appPrincipal = new ClaimsPrincipal(incoming);
            // incoming.Identities.First().AddClaim(new Claim("appSpecific", "some_value"));

            return Task.FromResult(appPrincipal);
        });
    }
公共类启动{
公共无效配置(IAppBuilder appBuilder){
//添加身份验证
此.AddAuthentication(appBuilder);
HttpConfiguration config=新的HttpConfiguration();
var container=CreateAutofacContainer();
var resolver=新的AutofacWebApidenceResolver(容器);
config.dependencyrolver=解析程序;
WebApiConfig.Register(配置);
config.EnsureInitialized();
//注册配置-在此之后无法向管道添加任何内容
appBuilder.useAutofacidleware(容器);
appBuilder.UseAutofacWebApi(配置);
appBuilder.UseWebApi(配置);
}
专用静态IContainer CreateAutofacContainer(){
var autofacBuilder=newcontainerbuilder();
var assembly=assembly.getExecutionGassembly();
//注册您的Web API控制器。
autofacBuilder.RegisterApicController(组件);
//用于一般日志记录实现
autofacBuilder.RegisterType().As();
//创建要在OWIN管道中填充的空使用上下文
IUsageContext usageContext=新的RuntimeUsageContext();
autofacBuilder.RegisterInstance(usageContext).As().SingleInstance();
//我们需要建立使用上下文
autofacBuilder.RegisterType().InstancePerRequest();
var container=autofacBuilder.Build();
返回容器;
}
私有void AddAuthentication(IAppBuilder应用程序){
var options=new IdentityServerBearerTokenAuthenticationOptions();
options.Authority=“MYAUTHORITY”;
options.RequiredScopes=new[]{“openid”、“profile”、“email”、“api”};
options.ValidationMode=ValidationMode.ValidationEndpoint;
app.useIdentityServerBearnerTokenauthentication(选项);
//如果需要,添加本地索赔
app.UseClaimsTransformation(传入=>{
//将索赔添加到传入索赔,或创建新的主体索赔
var appPrincipal=新的ClaimsPrincipal(传入);
//incoming.identies.First().AddClaim(新声明(“appSpecific”、“some_值”);
返回Task.FromResult(appPrincipal);
});
}
我使用的是混合流,api是从SPA应用程序调用的。我已经验证过(通过直接调用我的identity server的端点)该访问令牌是有效的,并且存在可用的声明。我还下载了IdentityServer.AccessTokenValidation项目并将其作为引用附加。当我为该项目中的方法设置一些断点时,它们从未被调用。这就是为什么我认为我的启动和OWIN管道出现问题的原因

我已经在我的启动中声明了UsageContext。它是一个我用来收集声明和一些配置设置的类,将被注入到实际的控制器中。我认为这是处理这个问题的好方法,所以在控制器中总是有有效的UsageContext可用

我已经阅读了很多样本和例子,但仍然没有发现完全相同的情况。我将感谢任何能为我指出正确方向的尝试

问候,,
Borre

可能是您将
UsageContext
注册为一个单件吗?您提到这个类包含声明,所以这个对象应该在pr http请求后解析,不是吗?

可能是您将
UsageContext
注册为一个单件吗?您提到这个类包含声明,所以这个对象应该是解析的ved曾经请求过http请求,是吗?

结果是AccessTokenValidation-库中有一行神秘的代码不起作用。我使用该库获取索赔。更改代码行后,一切似乎都正常

所以基本上我的问题现在已经结束了,一切都正常了。但我仍然不完全相信这是正确的方法


谢谢John的评论!

事实证明,AccessTokenValidation-库中有一条神秘的线不起作用。我使用该库获取索赔。更改线后,一切似乎都正常

所以基本上我的问题现在已经结束了,一切都正常了。但我仍然不完全相信这是正确的方法


谢谢John的评论!

您是否已注册全局授权筛选器或使用authorize修饰您的APIController?我已尝试使用authorize属性,但没有尝试使用全局授权筛选器。我不知道在控制器中使用全局筛选器或属性是否有任何区别。ApiC上的Auth属性OnController应该足够了。您可以调试并看到您的ClaimsPrincipal有0个声明,或者只是没有您期望的声明..?或者它根本不是ClaimsPrincipal?它根本没有声明。我有检查,但我非常确定也没有ClaimsPrincipal。启动中的代码创建了它。您是否注册了全局授权筛选器或用Authorize修饰ApiController?我尝试过使用Authorize属性,但没有尝试使用全局授权筛选器。我不知道在控制器中使用全局筛选器或属性是否有任何区别。ApiController上的Auth属性应该足够了。您可以调试并查看ClaimsPrincipal是否有0声明s、 或者根本不是你期望的声明?或者根本不是ClaimsPrincipal?它根本没有声明。我已经检查过了,但我非常确定也没有ClaimsPrincipal。我的初创公司中的代码创建了它。它应该,这是一个好观点!我认为它仍然与原始问题无关,因为构建UsageContext的部分代码是