Web API 与 OAUTH 使用 Swagger / Swashbuckle
Web API with OAUTH using Swagger / Swashbuckle
我正在尝试让我的 Web API 项目使用 Swagger 'pretty' 文档等。(http://swagger.io/)
我正在使用 Swashbuckle for .NET,它是从 NuGet 安装的,我使用的版本是 4.0.1
我已经能够安装和使用 Swagger。此时一切似乎都很正常。我唯一的障碍是禁用 API 密钥并能够使用 OAuth,就像在 PetStore 示例中一样 (http://petstore.swagger.wordnik.com/#!/pet/addPet)
我已经尝试了所有可以在网上找到的方法。让我在下面列出它们:
首先,这是我的 Startup.cs
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
Swashbuckle.Bootstrapper.Init(config);
}
现在,我的 SwaggerConfig.cs:
public static void Register()
{
Swashbuckle.Bootstrapper.Init(GlobalConfiguration.Configuration);
SwaggerSpecConfig.Customize(c =>
{
c.IgnoreObsoleteActions();
c.IncludeXmlComments(GetXmlCommentsPath());
c.ApiInfo(new Info
{
Title = "Work you",
Description = "testing some stuffs",
Contact = "Email@email.com"
});
c.Authorization("oauth2", new Authorization
{
Type = "oauth2",
Scopes = new List<Scope>
{
new Scope { ScopeId = "products.read", Description = "View products" },
new Scope { ScopeId = "products.manage", Description = "Manage products" }
},
GrantTypes = new GrantTypes
{
ImplicitGrant = new ImplicitGrant
{
LoginEndpoint = new LoginEndpoint
{
Url = "https://www.mysecure.website.com"
},
TokenName = "access_token"
}
}
});
});
SwaggerUiConfig.Customize(c =>
{
c.EnableOAuth2Support("client_id", "test-realm", "app Name");
var thisAssembly = typeof(SwaggerConfig).Assembly;
c.SupportHeaderParams = true;
c.DocExpansion = DocExpansion.List;
c.SupportedSubmitMethods = new[] { HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Head };
c.EnableDiscoveryUrlSelector();
});
}
我有一个 SwaggerExtensions 文件夹,里面有我需要的文件。例如:
我 类 装饰有:
[ScopeAuthorize("this.scope")]
但是,OAuth 选项从未在 swagger 页面上为我显示。我也看不到应该在哪里输入自定义 headers。
我确实看到标题和文档描述、电子邮件地址等正在从 SwaggerConfig.cs 中读取,所以我知道它至少被读取了。
我想不通。 :(
有什么想法吗?
默认情况下,swagger-ui 不显示 OAuth2 集成。
要启用它,您需要按照以下步骤操作:
- 确保
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
包含在 index.html 顶部的脚本列表中。它应该默认存在。
在 index.html 底部的 SwaggerUi 声明中,取消注释以下代码段(默认情况下已注释):
/*
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
*/
您可能希望使用自己的设置修改 clientId
、realm
和 appName
。
我得到了我的解决方案。这很强大,只是不是 100% 直接配置。
以下是我采取的步骤:
安装 NuGet 包,我使用 PM> Install-Package Swashbuckle -Version 4.1.0
但 link 位于 https://www.nuget.org/packages/Swashbuckle/,我建议获取最新版本,但我知道 4.1.0 有效。 EDIT 我刚刚更新到 5.X 但它坏了。 4.1.0 有效但最新的没有。我还没有进一步研究原因。
一旦你安装了这个,你就差不多完成了。
安装将创建一个 SwaggerConfig.cs 文件。这是我使用的代码(复制自 github master)
public class SwaggerConfig
{
public static void Register()
{
Swashbuckle.Bootstrapper.Init(GlobalConfiguration.Configuration);
SwaggerSpecConfig.Customize(c =>
{
c.IgnoreObsoleteActions();
//c.SupportMultipleApiVersions(
// new[] { "1.0", "2.0" },
// ResolveVersionSupportByRouteConstraint);
//c.PolymorphicType<Animal>(ac => ac
// .DiscriminateBy(a => a.Type)
// .SubType<Kitten>());
c.OperationFilter<AddStandardResponseCodes>();
c.OperationFilter<AddAuthResponseCodes>();
c.OperationFilter<AddOAuth2Scopes>();
//c.IncludeXmlComments(GetXmlCommentsPath());
c.ApiInfo(new Info
{
Title = "Swashbuckle Dummy",
Description = "For testing and experimenting with Swashbuckle features",
Contact = "someone@somewhere.com"
});
c.Authorization("oauth2", new Authorization
{
Type = "oauth2",
Scopes = new List<Scope>
{
new Scope { ScopeId = "test1", Description = "test1" },
new Scope { ScopeId = "test2", Description = "test2" }
},
GrantTypes = new GrantTypes
{
ImplicitGrant = new ImplicitGrant
{
LoginEndpoint = new LoginEndpoint
{
Url = "https://your.Oauth.server/Authorize"
},
TokenName = "access_token"
}
}
});
});
SwaggerUiConfig.Customize(c =>
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
c.SupportHeaderParams = true;
c.DocExpansion = DocExpansion.List;
c.SupportedSubmitMethods = new[] { HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Head };
//c.InjectJavaScript(typeof(SwaggerConfig).Assembly, "WebApplication4.SwaggerExtensions.onComplete.js");
//c.EnableDiscoveryUrlSelector();
//c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js");
//c.InjectStylesheet(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
c.EnableOAuth2Support("client_id", "realm", "Swagger UI");
});
// NOTE: If you want to customize the generated swagger or UI, use SwaggerSpecConfig and/or SwaggerUiConfig here ...
}
private static string GetXmlCommentsPath()
{
return String.Format(@"{0}\XmlComments.xml", AppDomain.CurrentDomain.BaseDirectory);
}
现在我们已经告诉 Swagger 我们想要使用 OAuth,这就是我们想要使用它的方式。完成了,对吧?没有。
您需要将此文件夹和文件添加到您的解决方案中:https://github.com/domaindrivendev/Swashbuckle/tree/master/Swashbuckle.Dummy.Core/SwaggerExtensions
(您只需要 .cs 文件)
确保你的命名空间是正确的...
然后,您需要在 WebAPI 中装饰您的 class,如下所示:
[ScopeAuthorize("test1")]
现在,当您 运行 它并到达 swagger 页面时,您将看到具有该声明的每个操作都将在右上角显示 OAuth 开关。单击它时,您可以使用隐式授权流程并获得将添加到您的请求中的令牌。
这仅适用于我发现的隐式授权。看起来他们确实试图让 AuthorizationCode Grant 继续运行,但他们构建的 js 文件仅支持隐式,据我所知。
希望这对某人有所帮助。这是一个强大的工具,我希望我们看到更多的网站使用这样的工具。
谢谢,祝你好运!
我觉得你原来的大部分都没问题。我正在使用 Swashbuckle 5.2.1 并且运行良好。我刚刚写了一篇博客 post (http://knowyourtoolset.com/2015/08/secure-web-apis-with-swagger-swashbuckle-and-oauth2-part-2/) 详细解释了这一点,但要点是添加 OperationFilter class(es) 来定义你的 API 方法将获得 OAuth21 切换按钮。如上所述,GitHub 的 SwaggerExtensions 文件夹中有这些定义的(示例),但实际上您至少需要一个 class 实现 IOperationFilter 及其 Apply 方法。我在下面有一个示例 class。 class 名称真的无关紧要(它在哪里也不重要),您只需要将它(以及任何其他名称,如果您有更多)包含在指定 OperationFilter(s) 的 SwaggerConfig 中。
public class AssignOAuth2SecurityRequirements : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
var allowsAnonymous = actFilters.Select(f => f.Instance).OfType<OverrideAuthorizationAttribute>().Any();
if (allowsAnonymous)
return; // must be an anonymous method
//var scopes = apiDescription.ActionDescriptor.GetFilterPipeline()
// .Select(filterInfo => filterInfo.Instance)
// .OfType<AllowAnonymousAttribute>()
// .SelectMany(attr => attr.Roles.Split(','))
// .Distinct();
if (operation.security == null)
operation.security = new List<IDictionary<string, IEnumerable<string>>>();
var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
{
{"oauth2", new List<string> {"sampleapi"}}
};
operation.security.Add(oAuthRequirements);
}
}
我正在尝试让我的 Web API 项目使用 Swagger 'pretty' 文档等。(http://swagger.io/)
我正在使用 Swashbuckle for .NET,它是从 NuGet 安装的,我使用的版本是 4.0.1
我已经能够安装和使用 Swagger。此时一切似乎都很正常。我唯一的障碍是禁用 API 密钥并能够使用 OAuth,就像在 PetStore 示例中一样 (http://petstore.swagger.wordnik.com/#!/pet/addPet)
我已经尝试了所有可以在网上找到的方法。让我在下面列出它们:
首先,这是我的 Startup.cs
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
Swashbuckle.Bootstrapper.Init(config);
}
现在,我的 SwaggerConfig.cs:
public static void Register()
{
Swashbuckle.Bootstrapper.Init(GlobalConfiguration.Configuration);
SwaggerSpecConfig.Customize(c =>
{
c.IgnoreObsoleteActions();
c.IncludeXmlComments(GetXmlCommentsPath());
c.ApiInfo(new Info
{
Title = "Work you",
Description = "testing some stuffs",
Contact = "Email@email.com"
});
c.Authorization("oauth2", new Authorization
{
Type = "oauth2",
Scopes = new List<Scope>
{
new Scope { ScopeId = "products.read", Description = "View products" },
new Scope { ScopeId = "products.manage", Description = "Manage products" }
},
GrantTypes = new GrantTypes
{
ImplicitGrant = new ImplicitGrant
{
LoginEndpoint = new LoginEndpoint
{
Url = "https://www.mysecure.website.com"
},
TokenName = "access_token"
}
}
});
});
SwaggerUiConfig.Customize(c =>
{
c.EnableOAuth2Support("client_id", "test-realm", "app Name");
var thisAssembly = typeof(SwaggerConfig).Assembly;
c.SupportHeaderParams = true;
c.DocExpansion = DocExpansion.List;
c.SupportedSubmitMethods = new[] { HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Head };
c.EnableDiscoveryUrlSelector();
});
}
我有一个 SwaggerExtensions 文件夹,里面有我需要的文件。例如:
我 类 装饰有:
[ScopeAuthorize("this.scope")]
但是,OAuth 选项从未在 swagger 页面上为我显示。我也看不到应该在哪里输入自定义 headers。
我确实看到标题和文档描述、电子邮件地址等正在从 SwaggerConfig.cs 中读取,所以我知道它至少被读取了。
我想不通。 :(
有什么想法吗?
默认情况下,swagger-ui 不显示 OAuth2 集成。
要启用它,您需要按照以下步骤操作:
- 确保
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
包含在 index.html 顶部的脚本列表中。它应该默认存在。 在 index.html 底部的 SwaggerUi 声明中,取消注释以下代码段(默认情况下已注释):
/* initOAuth({ clientId: "your-client-id", realm: "your-realms", appName: "your-app-name" }); */
您可能希望使用自己的设置修改 clientId
、realm
和 appName
。
我得到了我的解决方案。这很强大,只是不是 100% 直接配置。
以下是我采取的步骤:
安装 NuGet 包,我使用 PM> Install-Package Swashbuckle -Version 4.1.0
但 link 位于 https://www.nuget.org/packages/Swashbuckle/,我建议获取最新版本,但我知道 4.1.0 有效。 EDIT 我刚刚更新到 5.X 但它坏了。 4.1.0 有效但最新的没有。我还没有进一步研究原因。
一旦你安装了这个,你就差不多完成了。
安装将创建一个 SwaggerConfig.cs 文件。这是我使用的代码(复制自 github master)
public class SwaggerConfig
{
public static void Register()
{
Swashbuckle.Bootstrapper.Init(GlobalConfiguration.Configuration);
SwaggerSpecConfig.Customize(c =>
{
c.IgnoreObsoleteActions();
//c.SupportMultipleApiVersions(
// new[] { "1.0", "2.0" },
// ResolveVersionSupportByRouteConstraint);
//c.PolymorphicType<Animal>(ac => ac
// .DiscriminateBy(a => a.Type)
// .SubType<Kitten>());
c.OperationFilter<AddStandardResponseCodes>();
c.OperationFilter<AddAuthResponseCodes>();
c.OperationFilter<AddOAuth2Scopes>();
//c.IncludeXmlComments(GetXmlCommentsPath());
c.ApiInfo(new Info
{
Title = "Swashbuckle Dummy",
Description = "For testing and experimenting with Swashbuckle features",
Contact = "someone@somewhere.com"
});
c.Authorization("oauth2", new Authorization
{
Type = "oauth2",
Scopes = new List<Scope>
{
new Scope { ScopeId = "test1", Description = "test1" },
new Scope { ScopeId = "test2", Description = "test2" }
},
GrantTypes = new GrantTypes
{
ImplicitGrant = new ImplicitGrant
{
LoginEndpoint = new LoginEndpoint
{
Url = "https://your.Oauth.server/Authorize"
},
TokenName = "access_token"
}
}
});
});
SwaggerUiConfig.Customize(c =>
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
c.SupportHeaderParams = true;
c.DocExpansion = DocExpansion.List;
c.SupportedSubmitMethods = new[] { HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Head };
//c.InjectJavaScript(typeof(SwaggerConfig).Assembly, "WebApplication4.SwaggerExtensions.onComplete.js");
//c.EnableDiscoveryUrlSelector();
//c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js");
//c.InjectStylesheet(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
c.EnableOAuth2Support("client_id", "realm", "Swagger UI");
});
// NOTE: If you want to customize the generated swagger or UI, use SwaggerSpecConfig and/or SwaggerUiConfig here ...
}
private static string GetXmlCommentsPath()
{
return String.Format(@"{0}\XmlComments.xml", AppDomain.CurrentDomain.BaseDirectory);
}
现在我们已经告诉 Swagger 我们想要使用 OAuth,这就是我们想要使用它的方式。完成了,对吧?没有。
您需要将此文件夹和文件添加到您的解决方案中:https://github.com/domaindrivendev/Swashbuckle/tree/master/Swashbuckle.Dummy.Core/SwaggerExtensions
(您只需要 .cs 文件)
确保你的命名空间是正确的...
然后,您需要在 WebAPI 中装饰您的 class,如下所示:
[ScopeAuthorize("test1")]
现在,当您 运行 它并到达 swagger 页面时,您将看到具有该声明的每个操作都将在右上角显示 OAuth 开关。单击它时,您可以使用隐式授权流程并获得将添加到您的请求中的令牌。
这仅适用于我发现的隐式授权。看起来他们确实试图让 AuthorizationCode Grant 继续运行,但他们构建的 js 文件仅支持隐式,据我所知。
希望这对某人有所帮助。这是一个强大的工具,我希望我们看到更多的网站使用这样的工具。
谢谢,祝你好运!
我觉得你原来的大部分都没问题。我正在使用 Swashbuckle 5.2.1 并且运行良好。我刚刚写了一篇博客 post (http://knowyourtoolset.com/2015/08/secure-web-apis-with-swagger-swashbuckle-and-oauth2-part-2/) 详细解释了这一点,但要点是添加 OperationFilter class(es) 来定义你的 API 方法将获得 OAuth21 切换按钮。如上所述,GitHub 的 SwaggerExtensions 文件夹中有这些定义的(示例),但实际上您至少需要一个 class 实现 IOperationFilter 及其 Apply 方法。我在下面有一个示例 class。 class 名称真的无关紧要(它在哪里也不重要),您只需要将它(以及任何其他名称,如果您有更多)包含在指定 OperationFilter(s) 的 SwaggerConfig 中。
public class AssignOAuth2SecurityRequirements : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
var allowsAnonymous = actFilters.Select(f => f.Instance).OfType<OverrideAuthorizationAttribute>().Any();
if (allowsAnonymous)
return; // must be an anonymous method
//var scopes = apiDescription.ActionDescriptor.GetFilterPipeline()
// .Select(filterInfo => filterInfo.Instance)
// .OfType<AllowAnonymousAttribute>()
// .SelectMany(attr => attr.Roles.Split(','))
// .Distinct();
if (operation.security == null)
operation.security = new List<IDictionary<string, IEnumerable<string>>>();
var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
{
{"oauth2", new List<string> {"sampleapi"}}
};
operation.security.Add(oAuthRequirements);
}
}