【问题标题】:Enable Oauth2 client credentials flow in Swashbuckle在 Swashbuckle 中启用 Oauth2 客户端凭据流
【发布时间】:2016-09-30 03:30:37
【问题描述】:

我正在使用 IdentityServer3 来保护具有客户端凭据授权的 Web API。对于文档,我正在使用 Swashbuckle,但无法弄清楚如何在 SwaggerConfig 中为客户端凭据(应用程序)流启用 Oauth2。任何帮助将不胜感激!

【问题讨论】:

  • 您找到解决方案了吗?
  • 抱歉说不。我们决定不在生产中使用 swagger,这为我们解决了这个问题。

标签: oauth-2.0 identityserver3 swashbuckle


【解决方案1】:

我能够得到这个工作。大部分答案都可以在here找到。

为了让 client_credential 授权发挥作用,我必须更改一些部分。 第一部分在 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");
  });

这里的重要变化是.Flow("application") 我也使用了.TokenUrl 调用而不是.AuthorizationUrl 这只是取决于您设置的特定授权方案。

我还使用了一个略有不同的AssignOAuth2SecurityRequirements

public class AssignOAuth2SecurityRequirements : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
      var authorized = apiDescription.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>();
      if (!authorized.Any()) return;

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

      var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
      {
          {"oauth2", Enumerable.Empty<string>()}
      };

      operation.security.Add(oAuthRequirements);
    }
}

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

【讨论】:

  • 有什么办法可以让swagger doc的消费者提供client_id或者client_id和secret_key?
  • 当然,这就是您进行身份验证的方式。只需使用“grant_type:client_credentials”、“client_id:”和“secret_key:”创建一个登录表单 POST 请求,并将其发布到令牌 url。然后你将 OAuthAuthorizationServerProvider 子类化来处理登录。
  • 我应该更具体...我的意思是通过弹出的表格。
【解决方案2】:

我在让这一切正常工作时遇到了一些麻烦,但经过一番坚持后,我找到了一个无需将任何 JavaScript 注入 SwaggerUI 即可工作的解决方案。注意:我的部分困难可能是由于使用了 IdentityServer3,这是一个很棒的产品,只是不知道配置问题。

我的大部分更改都类似于上面的账单答案,但我的操作过滤器不同。在我的控制器中,所有方法都有一个 Authorize 标签,没有像这样的角色:

[Authorize]
// Not this
[Authorize(Roles = "Read")] // This doesn't work for me.

没有在 Authorize 标签上定义角色,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);
        }
    }

SwaggerConfig 如下所示:

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"
            );
        });
}

最后一部分是最难弄清楚的,我终于在 Chrome 开发者工具的帮助下完成了,该工具在网络标签上显示了一个红色的小 X,显示以下错误消息:

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.

我在Swagger UI not parsing reponse 描述了这个错误,这是由于 IdentityServer3 没有正确添加“Access-Control-Allow-Origin:http://localhost:62561”的响应标头您可以通过将客户端创建更新为来强制 IdentityServer3 发送该标头如下:

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"
    }
}    

AllowedCorsOrigins 是我拼图的最后一块。希望这可以帮助面临同样问题的其他人

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 2012-12-17
    • 1970-01-01
    • 2023-04-09
    • 2020-12-25
    • 1970-01-01
    • 2022-08-06
    • 2016-09-28
    • 2022-01-26
    相关资源
    最近更新 更多