Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I tell swashbuckle to add a required header #501

Closed
christopheblin opened this issue Sep 17, 2015 · 19 comments
Closed

How do I tell swashbuckle to add a required header #501

christopheblin opened this issue Sep 17, 2015 · 19 comments

Comments

@christopheblin
Copy link

I have one of my API controller that requires a header to be present (this is not a security header).

From what I've found on the internet (http://stackoverflow.com/questions/26742521/sending-dynamic-custom-headers-in-swagger-ui-try-outs), in java you can use http://docs.swagger.io/swagger-core/apidocs/com/wordnik/swagger/annotations/ApiImplicitParam.html with a paramType="header"

@ApiImplicitParams(
    { @ApiImplicitParam(paramType="header", name="X-CurrentLocale", dataType="string") }
)

How do I do the same in Swashbuckle ?

@bhupinder7
Copy link

HI there, If you are customizing the index.html page then you can add your own header by changing the addApiKeyAuthorization javascript function in the index.html page and by adding below properties in the SwaggerConfig.cs class.

SwaggerConfig.cs

config.EnableSwagger(
c =>
{
c.ApiKey("apiKey")
.Description("API Key Authentication")
.Name("apiKey")
.In("header");
})

function addApiKeyAuthorization() {
var key = encodeURIComponent($('#input_apiKey')[0].value);
if (key && key.trim() != "") {

          key = "Bearer " + key;

          var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", key, "header");
          window.swaggerUi.api.clientAuthorizations.add("key", apiKeyAuth);
          log("added key " + key);
      }
  }

@domaindrivendev
Copy link
Owner

In addition, if you'd like to list the header as a parameter with each operation description, you can just wire it up via an IOperationFilter (see readme). Here's some sample code to get you started:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
            {
                name = "Foo-Header",
                @in = "header",
                type = "string",
                required = true
            });
    }
} 

@bunny1985
Copy link

it does not close all use cases at all.
For exampel i Want to document Requested with and __CSRFToken headers.
NMote that CSRF token will be necesary only for "POST LIKE" actions - not for "GET"
How could i do it ?

@VisualBean
Copy link

I know this is sort of old, but I will respond anyway, as I was led here by some google-fu

it does not close all use cases at all.
For exampel i Want to document Requested with and __CSRFToken headers.
NMote that CSRF token will be necesary only for "POST LIKE" actions - not for "GET"
How could i do it ?

If you document your actions with [HttpGet], [HttpPut], [HttpPost] etc.
you can quite easily create an operationsfilter to find all Post actions

var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline().Where( f => f.Scope == FilterScope.Action );
var isPostOperation = filterPipeline.Select(f => f.Instance).OfType<HttpPostAttribute>().FirstOrDefault() !=
                        null;

@mrugeshparekh
Copy link

mrugeshparekh commented Jul 7, 2017

My swagger UI is generated automatically.
I am trying to add apikey to each request header. But some reason how its not added to each header.
For example its not added to http://localhost/swagger/ui/index
My config looks like following. (C#)

GlobalConfiguration.Configuration 
                .EnableSwagger(c =>
                    {
                        c.SingleApiVersion("Version1", "API");

                        // NOTE: You must also configure 'EnableApiKeySupport' below in the SwaggerUI section
                        c.ApiKey("apiKey")
                            .Description("API Key Authentication")
                            .Name("Token")
                            .In("header");
                        
                        c.IncludeXmlComments(GetXmlCommentsPath());
                        
                        c.UseFullTypeNameInSchemaIds();
						
                        c.OperationFilter<AddDefaultHeader>();
						
                        c.ResolveConflictingActions(apiDescriptions => apiDescriptions.FirstOrDefault());                       
                    })
                .EnableSwaggerUi(c =>
                    {
                        c.InjectStylesheet(thisAssembly, "API.Content.SwaggerStyle.css");

                        

                        // If your API supports ApiKey, you can override the default values.
                        // "apiKeyIn" can either be "query" or "header"                                                
                        //
                        c.EnableApiKeySupport("apiKey", "header");
                    });

@bkwdesign
Copy link

Following upon @VisualBean 's example, I created this special header for my OData V4 patch requests.
FWIW - scaffolded OData controllers don't decorate "Patch" actions with the HttpPatchAttribute, so, I modified this look either for the attribute, or for simply the action name "Patch"

public class AssignReturnRepresentationHeader : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {

        var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline().Where(f => f.Scope == FilterScope.Action);
        var isNamedPatch = apiDescription.ActionDescriptor.ActionName == "Patch";
        var isPatchOperation = filterPipeline.Select(f => f.Instance).OfType<HttpPatchAttribute>().FirstOrDefault() != null || isNamedPatch;
        

        if (!isPatchOperation)
            return;

        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
        {
            name = "Prefer",
            @in = "header",
            type = "string",
            @default = "return=representation",
            description = "For OData V4 this header is needed if you want to return a representation of the changed entity.",
            required = true
        });
    }
}

@abhargavasharma
Copy link

abhargavasharma commented May 14, 2018

If you copy and paste below code SwaggerConfig.cs, it will work.

using System.Web.Http;
using WebActivatorEx;
using OAuthTokenBasedRestService;
using Swashbuckle.Application;
using Swashbuckle.Swagger;
using System.Web.Http.Description;
using System.Collections.Generic;

[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

namespace OAuthTokenBasedRestService
{
	public class SwaggerConfig
	{
		public static void Register()
		{
			var thisAssembly = typeof(SwaggerConfig).Assembly;

			GlobalConfiguration.Configuration
				.EnableSwagger(c =>
					{
						c.SingleApiVersion("v1", "OAuthTokenBasedRestService");
						c.OperationFilter<AddRequiredAuthorizationHeaderParameter>();
					})
				.EnableSwaggerUi(c =>
					{
						c.EnableApiKeySupport("apiKey", "header");
					});

		}
	}

	public class AddRequiredAuthorizationHeaderParameter : IOperationFilter
	{
		public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
		{
			if (operation.parameters == null)
				operation.parameters = new List<Parameter>();

			operation.parameters.Add(new Parameter
			{
				name = "Authorization",
				@in = "header",
				type = "string",
				required = true,
				description = "access token"
			});
		}
	}
	
}

@ayeshathecoder
Copy link

@abhargavasharma it is not coming on the UI. I have tried all the above solutions.
Can anyone provide the screenshot and any test urls for auth and token.

@i7657043
Copy link

@ayeshathecoder

Create a new Class named CustomFilters in the namespaceFooSpace.Filters and add the following code.

using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;

namespace FooSpace.Filters
{
    public class CustomFilters
    {
        public class AuthHeaderFilter : IOperationFilter
        {
            public void Apply(Operation operation, OperationFilterContext context)
            {
                if (operation.Parameters == null)
                    operation.Parameters = new List<IParameter>();
                

                operation.Parameters.Add(new NonBodyParameter
                {
                    Name = "Authorization",
                    In = "header",
                    Type = "string",
                    Required = false,
                    Default = "Bearer "
                });
            }
        }
    }
}

In Startup.cs, in the ConfigureServices() method add the following lines of code after services.AddMvc();:

services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "API", Version = "v1" });
                c.OperationFilter<Filters.CustomFilters.AuthHeaderFilter>();
            });


@ayeshathecoder
Copy link

ayeshathecoder commented Aug 30, 2018 via email

@Chris-Upshop
Copy link

In addition, if you'd like to list the header as a parameter with each operation description, you can just wire it up via an IOperationFilter (see readme). Here's some sample code to get you started:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
            {
                name = "Foo-Header",
                @in = "header",
                type = "string",
                required = true
            });
    }
} 

This works great but is there a way to do this and then exclude it from one or two places?

@javafun
Copy link

javafun commented Mar 5, 2019

Can anyone suggest me how to add token parameter to get method?

@iby-dev
Copy link

iby-dev commented Mar 5, 2019

@cward-ADC is what i used to do add a token parameter.

@rohanaceres
Copy link

AddDefaultHeader

Can I add a required parameter without generics?
I'm trying to add them dynamically using reflection.

@tojoirinah
Copy link

In addition, if you'd like to list the header as a parameter with each operation description, you can just wire it up via an IOperationFilter (see readme). Here's some sample code to get you started:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
            {
                name = "Foo-Header",
                @in = "header",
                type = "string",
                required = true
            });
    }
} 

This works great but is there a way to do this and then exclude it from one or two places?

It works only for post method, how about get ?

@celsojr
Copy link

celsojr commented Apr 10, 2020

In addition, if you'd like to list the header as a parameter with each operation description, you can just wire it up via an IOperationFilter (see readme). Here's some sample code to get you started:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
            {
                name = "Foo-Header",
                @in = "header",
                type = "string",
                required = true
            });
    }
} 

This works great but is there a way to do this and then exclude it from one or two places?

It works only for post method, how about get ?

[HttpGet]
public IActionResult Get([FromHeader(Name = "Foo-Header")] string mediaType)
{
    // TODO: something
}

@Thaval
Copy link

Thaval commented Sep 22, 2020

I don't know how this works for you guys, but my OperationFilter is applied AFTER the request, which means first my Web API Controller is called and THEN this operation filter runs. Actually I wanted to have swagger add some custom headers to the request. Everyone says IOperationFilter is the answer, but I'm pretty sure it's not.

@Thaval
Copy link

Thaval commented Sep 30, 2020

Got it, know how it is intended to work now.

@tonlopes21
Copy link

Também gostaria de saber como funciona, estou com o mesmo problema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests