Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oauth .NET核心OpenId连接服务器:跨多个应用程序共享同一令牌_Oauth_Asp.net Core_Openid Connect_Aspnet Contrib - Fatal编程技术网

Oauth .NET核心OpenId连接服务器:跨多个应用程序共享同一令牌

Oauth .NET核心OpenId连接服务器:跨多个应用程序共享同一令牌,oauth,asp.net-core,openid-connect,aspnet-contrib,Oauth,Asp.net Core,Openid Connect,Aspnet Contrib,我有两个用.NET Core编写的API,目标是4.6.1: myAuthApi():用于验证凭据并向客户端颁发令牌。它还有一个端点/api/values/1(此操作上有一个Authorize属性,用于验证令牌) myPublicApi():它在/api/values/1上从客户端接收令牌(此操作上具有Authorize属性,也用于验证令牌)。myPublicApi没有任何令牌端点,它是一个资源服务器 我正在使用AspNet.Security.OpenIdConnect.Server 1.0.0

我有两个用.NET Core编写的API,目标是4.6.1:

  • myAuthApi():用于验证凭据并向客户端颁发令牌。它还有一个端点/api/values/1(此操作上有一个Authorize属性,用于验证令牌)
  • myPublicApi():它在/api/values/1上从客户端接收令牌(此操作上具有Authorize属性,也用于验证令牌)。myPublicApi没有任何令牌端点,它是一个资源服务器
  • 我正在使用AspNet.Security.OpenIdConnect.Server 1.0.0。 这两个API都是Service.Fabric无状态服务

    我可以成功地将以下请求格式的令牌获取到

    在根据myAuthApi()验证令牌时,它会起作用。但是,当对myPublicApi()使用相同的标记时,它不会

    在这两个API中,在Startup.cs中,我都有

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Connect to Redis database.
            var redis = ConnectionMultiplexer.Connect(ConnectionHelper.GetRedisConnectionString(Configuration));
            services.AddDataProtection()
                .PersistKeysToRedis(redis, "DataProtection-Keys")
                .ProtectKeysWithCertificate(CertificateHandler.GetX509Certificate2(Configuration));
    
            // Add framework services.
            services.AddMvc().AddJsonOptions(opts =>
            {
                // we set the json serializer to follow camelCaseConventions when 
                // receiving /replying to JSON requests
                opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
            // we add authentication for the oAuth middleware to be registered in the DI container
            services.AddAuthentication();
        }
    
    在myPublicApi中,我有:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
    
            // Add a new middleware validating access tokens.
            app.UseOAuthValidation(options =>
            {
                // Automatic authentication must be enabled
                // for SignalR to receive the access token.
                options.AutomaticAuthenticate = true;
                options.Events = new OAuthValidationEvents
                {
                    // Note: for SignalR connections, the default Authorization header does not work,
                    // because the WebSockets JS API doesn't allow setting custom parameters.
                    // To work around this limitation, the access token is retrieved from the query string.
                    OnRetrieveToken = context =>
                    {
                        // Note: when the token is missing from the query string,
                        // context.Token is null and the JWT bearer middleware will
                        // automatically try to retrieve it from the Authorization header.
                        context.Token = context.Request.Query["access_token"];
    
                        return Task.FromResult(0);
                    }
                };
            });
    
            app.UseMvc();
        }
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            // Add a new middleware validating access tokens.
            app.UseOAuthValidation(options =>
            {
                // Automatic authentication must be enabled
                // for SignalR to receive the access token.
                options.AutomaticAuthenticate = true;
                options.Events = new OAuthValidationEvents
                {
                    // Note: for SignalR connections, the default Authorization header does not work,
                    // because the WebSockets JS API doesn't allow setting custom parameters.
                    // To work around this limitation, the access token is retrieved from the query string.
                    OnRetrieveToken = context =>
                    {
                        // Note: when the token is missing from the query string,
                        // context.Token is null and the JWT bearer middleware will
                        // automatically try to retrieve it from the Authorization header.
                        context.Token = context.Request.Query["access_token"];
    
                        return Task.FromResult(0);
                    }
                };
            });
    
            // Add a new middleware issuing access tokens.
            app.UseOpenIdConnectServer(options =>
            {
                options.Provider = new AuthenticationProvider();
                // Enable the logout, token and userinfo endpoints.
                options.LogoutEndpointPath = "/connect/logout";
                options.TokenEndpointPath = "/connect/token";
                options.UserinfoEndpointPath = "/connect/userinfo";
                CertificateHandler.SetupCommonAuthServerOptions(options, Configuration);
            });
    
            app.UseMvc();
        }
    
    在myAuthApi中,我有:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
    
            // Add a new middleware validating access tokens.
            app.UseOAuthValidation(options =>
            {
                // Automatic authentication must be enabled
                // for SignalR to receive the access token.
                options.AutomaticAuthenticate = true;
                options.Events = new OAuthValidationEvents
                {
                    // Note: for SignalR connections, the default Authorization header does not work,
                    // because the WebSockets JS API doesn't allow setting custom parameters.
                    // To work around this limitation, the access token is retrieved from the query string.
                    OnRetrieveToken = context =>
                    {
                        // Note: when the token is missing from the query string,
                        // context.Token is null and the JWT bearer middleware will
                        // automatically try to retrieve it from the Authorization header.
                        context.Token = context.Request.Query["access_token"];
    
                        return Task.FromResult(0);
                    }
                };
            });
    
            app.UseMvc();
        }
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            // Add a new middleware validating access tokens.
            app.UseOAuthValidation(options =>
            {
                // Automatic authentication must be enabled
                // for SignalR to receive the access token.
                options.AutomaticAuthenticate = true;
                options.Events = new OAuthValidationEvents
                {
                    // Note: for SignalR connections, the default Authorization header does not work,
                    // because the WebSockets JS API doesn't allow setting custom parameters.
                    // To work around this limitation, the access token is retrieved from the query string.
                    OnRetrieveToken = context =>
                    {
                        // Note: when the token is missing from the query string,
                        // context.Token is null and the JWT bearer middleware will
                        // automatically try to retrieve it from the Authorization header.
                        context.Token = context.Request.Query["access_token"];
    
                        return Task.FromResult(0);
                    }
                };
            });
    
            // Add a new middleware issuing access tokens.
            app.UseOpenIdConnectServer(options =>
            {
                options.Provider = new AuthenticationProvider();
                // Enable the logout, token and userinfo endpoints.
                options.LogoutEndpointPath = "/connect/logout";
                options.TokenEndpointPath = "/connect/token";
                options.UserinfoEndpointPath = "/connect/userinfo";
                CertificateHandler.SetupCommonAuthServerOptions(options, Configuration);
            });
    
            app.UseMvc();
        }
    
    如您所见,我的数据保护提供商正在Redis中存储密钥,我正在使用一个证书保护密钥,我正在这两个应用程序中共享该证书。 资源服务器没有配置任何身份验证提供程序,并且在启动时没有UseOpenIdConnectServer。在asp.net Web API 2中,令牌解密通常使用共享机器密钥跨应用程序进行管理

    如何使用oAuthValidation在所有其他应用程序中成功验证myAuthApi发布的令牌

    编辑,可以在此处看到一些日志:

    编辑2: 彻底阅读日志后,我发现令牌的解除保护使用的是相同的数据保护提供程序,但用途不同:

    "Performing unprotect operation to key {4406cfa7-a588-44ba-b73a-e25817d982d9} with purposes ('C:\SfDevCluster\Data\_App\_Node_4\TestMicroServicesType_App22\PublicApiPkg.Code.1.0.1', 'OpenIdConnectServerHandler', 'AccessTokenFormat', 'ASOS')."
    "Performing unprotect operation to key {4406cfa7-a588-44ba-b73a-e25817d982d9} with purposes ('C:\SfDevCluster\Data\_App\_Node_3\TestMicroServicesType_App22\AuthApiPkg.Code.1.0.1', 'OpenIdConnectServerHandler', 'AccessTokenFormat', 'ASOS')."
    
    要解决此问题,@PinpointTownes建议如下设置数据保护提供商:

        var redis = ConnectionMultiplexer.Connect(ConnectionHelper.GetRedisConnectionString(Configuration));
        services.AddDataProtection()
                 // set the application name to a common value in all apps 
                 // to have the same purpose and share the token across apps
                .SetApplicationName("MyTestMicroServices")
                .PersistKeysToRedis(redis, "DataProtection-Keys")
                .ProtectKeysWithCertificate(CertificateHandler.GetX509Certificate2(Configuration)); 
    

    调用
    services.AddDataProtection().SetApplicationName(“[您的应用程序名称]”)
    以确保您的两个API使用相同的鉴别器(用于派生加密密钥),并且它应该可以工作。

    我知道这篇文章非常古老。我也有同样的问题,这个解决方案可以与kestrel一起使用,但是如果尝试将IIS用于主机,则令牌不起作用。你听到过同样的话吗?