Oauth 2.0 在Swashbuckle中启用Oauth2客户端凭据流

Oauth 2.0 在Swashbuckle中启用Oauth2客户端凭据流,oauth-2.0,identityserver3,swashbuckle,Oauth 2.0,Identityserver3,Swashbuckle,Im使用IdentityServer3通过客户端凭据授权保护Web API。对于文档,我正在使用Swashback,但不知道如何在客户端凭据(应用程序)流的SwaggerConfig中启用Oauth2。任何帮助都将不胜感激 我能让它工作起来。大部分答案都可以找到 有几个部分我不得不改变,以使客户_证书授予工作。 第一部分是EnableSwagger和EnableSwaggerUi调用: config.EnableSwagger(c => { c.SingleApiVersio

Im使用IdentityServer3通过客户端凭据授权保护Web API。对于文档,我正在使用Swashback,但不知道如何在客户端凭据(应用程序)流的SwaggerConfig中启用Oauth2。任何帮助都将不胜感激

我能让它工作起来。大部分答案都可以找到

有几个部分我不得不改变,以使客户_证书授予工作。 第一部分是EnableSwagger和EnableSwaggerUi调用:

config.EnableSwagger(c => 
  {
    c.SingleApiVersion("v1", "sample api");
    c.OAuth2("oauth2")
     .Description("client credentials grant flow")
     .Flow("application")
     .Scopes(scopes => scopes.Add("sampleapi", "try out the sample api"))
     .TokenUrl("http://authuri/token");
    c.OperationFilter<AssignOAuth2SecurityRequirements>();
  }).EnableSwaggerUi(c =>
  {
    c.EnableOAuth2Support("sampleapi", "samplerealm", "Swagger UI");
  });

这应该足以让身份验证开关显示。对我来说,另一个问题是设置了默认身份验证对话框,因此用户只需选择一个范围,然后单击“授权”。在我的情况下,由于我设置身份验证的方式,这不起作用。我不得不在swagger-oauth.js脚本中重新编写该对话框,并将其注入到SwaggerUI中。

我在使这一切正常工作方面遇到了一些困难,但经过大量的坚持,我找到了一个解决方案,它可以在不必向SwaggerUI中注入任何JavaScript的情况下工作。注意:我的部分困难可能是由于使用IdentityServer3,这是一个很棒的产品,只是不知道配置问题

我的大多数更改与上面的账单答案相似,但我的操作过滤器不同。在我的控制器中,所有方法都有一个Authorize标记,没有这样的角色:

[Authorize]
// Not this
[Authorize(Roles = "Read")] // This doesn't work for me.
在授权标记上未定义角色的情况下,OperationFilter如下所示:

    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        // Correspond each "Authorize" role to an oauth2 scope, since I don't have any "Roles" defined, this didn't work
        // and is in most of the Apply methods I found online.  If you are like me and your [Authorize] tag doesn't contain
        // any roles this will not work.
        //var scopes = apiDescription.ActionDescriptor.GetFilterPipeline()
        //    .Select(filterInfo => filterInfo.Instance)
        //    .OfType<AuthorizeAttribute>()
        //    .SelectMany(attr => attr.Roles.Split(','))
        //    .Distinct();

        var scopes = new List<string>() { "Read" }; // For me I just had one scope that is added to all all my methods, you might have to be more selective on how scopes are added.

        if (scopes.Any())
        {
            if (operation.security == null)
                operation.security = new List<IDictionary<string, IEnumerable<string>>>();

            var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
            {
                { "oauth2", scopes }
            };

            operation.security.Add(oAuthRequirements);
        }
    }
public static void Register()
{
    var thisAssembly = typeof(SwaggerConfig).Assembly;
    GlobalConfiguration.Configuration
        .EnableSwagger(c =>
        {
           c.SingleApiVersion("v1", "waPortal");
           c.OAuth2("oauth2")
                .Description("OAuth2 Client Credentials Grant Flow")
                .Flow("application")
                .TokenUrl("http://security.RogueOne.com/core/connect/token")
                .Scopes(scopes =>
                {
                    scopes.Add("Read", "Read access to protected resources");
                });
            c.IncludeXmlComments(GetXmlCommentsPath());
            c.UseFullTypeNameInSchemaIds();
            c.DescribeAllEnumsAsStrings();
            c.OperationFilter<AssignOAuth2SecurityRequirements>();
        })
        .EnableSwaggerUi(c =>
        {
            c.EnableOAuth2Support(
                clientId: "swaggerUI",
                clientSecret: "BigSecretWooH00",
                realm: "swagger-realm",
                appName: "Swagger UI"
            );
        });
}
我在这里描述了这个错误,它是由于IdentityServer 3没有正确添加“Access Control Allow Origin:”响应头导致的。您可以通过将客户端创建更新为以下内容来强制IdentityServer 3发送该头:

new Client
{
    ClientName = "SwaggerUI",
    Enabled = true,
    ClientId = "swaggerUI",
    ClientSecrets = new List<Secret>
    {
        new Secret("PasswordGoesHere".Sha256())
    },
    Flow = Flows.ClientCredentials,
    AllowClientCredentialsOnly = true,
    AllowedScopes = new List<string>
    {
        "Read"
    },

    Claims = new List<Claim>
    {
        new Claim("client_type", "headless"),
        new Claim("client_owner", "Portal"),
        new Claim("app_detail", "allow")
    },
    PrefixClientClaims = false
    // Add the AllowedCorOrigins to get the Access-Control-Allow-Origin header to be inserted for the following domains
    ,AllowedCorsOrigins = new List<string>
    {
        "http://localhost:62561/"
        ,"http://portaldev.RogueOne.com"
        ,"https://portaldev.RogueOne.com"
    }
}    
新客户端
{
ClientName=“SwaggerUI”,
启用=真,
ClientId=“swaggerUI”,
ClientSecrets=新列表
{
新秘密(“PasswordGoesher.Sha256())
},
Flow=Flows.ClientCredentials,
AllowClientCredentially=true,
AllowedScopes=新列表
{
“读”
},
索赔=新名单
{
新索赔(“客户类型”、“无头”),
新索赔(“业主”、“门户”),
新索赔(“应用程序详情”、“允许”)
},
PrefixClientClaims=false
//添加AllowedCorOriginates以获取访问控制允许为以下域插入源文件头
,AllowedCorsOrigins=新列表
{
"http://localhost:62561/"
,"http://portaldev.RogueOne.com"
,"https://portaldev.RogueOne.com"
}
}    

被允许的科索里根人是我拼图的最后一块。希望这能帮助其他面临同样问题的人

您找到解决方案了吗?很抱歉,没有。我们决定在生产中不使用swagger,这为我们解决了这个问题。有没有办法允许swagger文档的消费者提供客户id或客户id和密钥?当然,这就是您进行身份验证的方式。只需创建一个带有“grant\u type:client\u credentials”、“client\u id:”和“secret\u key:”的登录表单POST请求,并将其发布到令牌url。然后您将对OAuthAuthorizationServerProvider进行子类化以处理登录。。。我是说通过弹出的表格。
XMLHttpRequest cannot load http://security.RogueOne.com/core/connect/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62561' is therefore not allowed access.
new Client
{
    ClientName = "SwaggerUI",
    Enabled = true,
    ClientId = "swaggerUI",
    ClientSecrets = new List<Secret>
    {
        new Secret("PasswordGoesHere".Sha256())
    },
    Flow = Flows.ClientCredentials,
    AllowClientCredentialsOnly = true,
    AllowedScopes = new List<string>
    {
        "Read"
    },

    Claims = new List<Claim>
    {
        new Claim("client_type", "headless"),
        new Claim("client_owner", "Portal"),
        new Claim("app_detail", "allow")
    },
    PrefixClientClaims = false
    // Add the AllowedCorOrigins to get the Access-Control-Allow-Origin header to be inserted for the following domains
    ,AllowedCorsOrigins = new List<string>
    {
        "http://localhost:62561/"
        ,"http://portaldev.RogueOne.com"
        ,"https://portaldev.RogueOne.com"
    }
}