public class BasicAuthMessageHandler : DelegatingHandler
{
private const string BasicAuthResponseHeader = "WWW-Authenticate";
private const string BasicAuthResponseHeaderValue = "Basic";
public BasicAuthMessageHandler(HttpMessageHandler innerHandler)
{
this.InnerHandler = innerHandler;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
AuthenticationHeaderValue authValue = request.Headers.Authorization;
HttpResponseMessage unauthorizedResponse = request.CreateUnauthorizedResponse();
if (authValue != null && !string.IsNullOrWhiteSpace(authValue.Parameter))
{
Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
if (parsedCredentials != null)
{
// TODO: Check that the user/pass are valid
if (parsedCredentials.Username == "user" &&
parsedCredentials.Password == "pass")
{
// If match, pass along to the inner handler
return base.SendAsync(request, cancellationToken);
}
}
}
else
{
// Prompt for creds
unauthorizedResponse.Headers.Add(BasicAuthResponseHeader, BasicAuthResponseHeaderValue);
}
return Task.FromResult(unauthorizedResponse);
}
private Credentials ParseAuthorizationHeader(string authHeader)
{
string[] credentials = Encoding.ASCII.GetString(Convert
.FromBase64String(authHeader))
.Split(
new[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0])
|| string.IsNullOrEmpty(credentials[1])) return null;
return new Credentials()
{
Username = credentials[0],
Password = credentials[1],
};
}
}
正在注册Swagger路由
// Do this after calling ConfigureSwagger
ConfigureSwagger(config);
// Remove the swagger_ui route and re-add it with the wrapped handler.
var route = config.Routes["swagger_ui"];
config.Routes.Remove("swagger_ui");
config.Routes.MapHttpRoute("swagger_ui", route.RouteTemplate, route.Defaults, route.Constraints, new BasicAuthMessageHandler(route.Handler));
1条答案
按热度按时间fcg9iug31#
先声明一句:即使你保护你的Swagger UI不被公众使用,你也没有保护你的API不被公众使用。你必须假设每个人都知道你的所有路由,并且有适当的安全措施来保护任何可能进入的请求。
Swashbuckle(将Swagger添加到Web API的部分)将一个自定义
HttpMessageHandler
添加到/swagger/ui
路由(如此处所示)。如果您查看Web API pipeline,您可以看到,如果指定一个自定义处理程序,则可以绕过所有Controller选择、Auth过滤器等。这就是此处所发生的情况。一些解决方案:
1.使用应用程序设置仅在调试模式下有条件地调用
ConfigureSwagger(config)
。这将阻止所有/swagger
路由将其投入生产。或者,您可以使用暂存槽并仅在那里添加它。1.你可以用Basic Auth MessageHandler这样的代码来 Package
SwaggerUiHandler
。如果用户选择/swagger/ui
路径,这将提示用户输入基本的creds。请看下面我对这段代码的修改版本。也许再多考虑一下,我们就能想出一个更好的解决方案--我在Swashbuckle repo中看到了几个问题(here和here),这表明您不是第一个遇到这个问题的人。
已修改的基本身份验证处理程序(来自here):
正在注册Swagger路由