ServiceStack API documentation in Swagger-UI behind the closed doors

Viewed 977

I want to allow access to swagger-ui and metadata only if user is authenticated (forms auth) on our web app, but I want to allow API access all the time (API have some public methods and some which require basic auth).

So what I did is I added this route prefix for API:

public override RouteAttribute[] GetRouteAttributes(Type requestType)
{
    var routes = base.GetRouteAttributes(requestType);
    routes.Each(x => x.Path = "/API" + x.Path);
    return routes;
}

And:

ServiceRoutes = new Dictionary<Type, string[]> {
{
         typeof(AuthenticateService), new[] { "/api/auth", "/api/auth/{provider}" }
     },
}

And this as well in web config:

<location path="api">
<system.web>
  <authorization>
    <allow users="*"/>
  </authorization>
</system.web>

And the thing is that when I go to /api/ now that works fine, but when I try invoke some method, I get redirected to my login route.

Is there a way to solve this like I started, or there's a better way to protect the documentation?

1 Answers

There's no explicit option to require Authentication on metadata pages but you can use a PreRequestFilter to protect access to the /metadata and /swagger-ui pages with:

PreRequestFilters.Add((req, res) =>
{
    if (req.PathInfo.StartsWith("/metadata") || req.PathInfo.StartsWith("/swagger-ui"))
    {
        var session = req.GetSession();
        if (!session.IsAuthenticated)
        {
            res.StatusCode = (int)HttpStatusCode.Unauthorized;
            res.EndRequest();
        }
    }
});

And to protect access to the /openapi JSON specification if you're using Swagger 2.0 / Open API Feature you can dynamically add the [Authenticate] attribute at runtime with:

public AppHost()
{
    typeof(OpenApiService)
        .AddAttributes(new AuthenticateAttribute());
}

If you're using the older Swagger 1.2 Plugin you can protect access to backend Services with:

public AppHost()
{
    typeof(SwaggerResource)
        .AddAttributes(new AuthenticateAttribute());
    typeof(SwaggerResources)
        .AddAttributes(new AuthenticateAttribute());
}

This assumes you're using ServiceStack Authentication not ASP.NET Auth.

Related