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

Show Authorization Header in UI #290

Closed
tiwari-abhishek opened this issue Apr 22, 2015 · 17 comments
Closed

Show Authorization Header in UI #290

tiwari-abhishek opened this issue Apr 22, 2015 · 17 comments

Comments

@tiwari-abhishek
Copy link

I have protected all my APIs with oAuth and need to be able to pass Access Token to the API through Authorization header in the try out UI. How can I do that? as of now I just have the Controller methods showing up which wont actually work without the header being passed.

Any help appreciated.

@billzhuang
Copy link

i also want to know how to implement this issue, i did not use OAuth, i just need pass a customized key in header, currently my workround is run below method in console
swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("x-accesskey", "eeee", "header"));

but is there any trick i can let me input header in swagger UI

@adamfisher
Copy link

I also need this. https://github.com/swagger-api/swagger-ui#header-parameters shows how to add it in swagger but I'm not seeing a way to do it from the config in Swashbuckle.

@jskrepnek
Copy link

Use an operation filter.

public class AddAuthorizationHeaderParameterOperationFilter: IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
            var isAuthorized = filterPipeline
                                             .Select(filterInfo => filterInfo.Instance)
                                             .Any(filter => filter is IAuthorizationFilter);

            var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();

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

Then add this filter to the configuration:

httpConfig
.EnableSwagger("docs/{apiVersion}", config => {
config.SingleApiVersion("v1", "api")
config.OperationFilter<AddAuthorizationHeaderParameterOperationFilter>();
})
.EnableSwaggerUi(config => {
config.DocExpansion(DocExpansion.Full);
 });

@MarwaAhmed
Copy link

I want to add the: "AddAuthorizationHeaderParameterOperationFilter" to specific service methods.
for ex: api/students ---> uses that certain header key-value.
and i want to add the basic authentication in a certain service method;
for ex: api/authenticate --> this uses basic http authentication.

any suggestions? thanks in advance.

@MarwaAhmed
Copy link

okay, i've figured it out. I'm just writing the solution in case if anyone faced it.

in "AddAuthorizationHeaderParameterOperationFilter"; "Apply" method:

var myTokenAttribute = apiDescription.GetControllerAndActionAttributes<MyToken>().Any();

//note: i wrote the attribute above a controller and sometimes above an actionmethod.
Then:

 if (myTokenAttribute)
 {           
     if (operation.parameters == null)
     {
          operation.parameters = new List<Parameter>();
      }            
      operation.parameters.Add(new Parameter()
      {
           name = "Authorization Token",
           @in = "header",
            description = "my token description",
            required = true,
            type = "string"
        });
   }

@domaindrivendev
Copy link
Owner

Nice - this is similar to what I would have recommended.

I'm not familiar with your implementation of MyToken, but I'm guessing it's just a "marker" attribute that has no effect on the actual implementation.

Although it's not always possible, I try to implement operation filters that are bound to actual implementation so you get "living" documentation. For example, I use the WebApi "Authorize" attribute to enforce authorization and then have an operation filter that includes the relevant header parameter if operation's are decorated with that attribute. This way, the documentation always reflects the actual behavior.

@MarwaAhmed
Copy link

@domaindrivendev: Yes, MyToken is an attribute which checks if the api's user is logged in & has a sessionId. Waiting for your documentation example; this is going to be very helpful. Would you please include http basic authentication with an actual example as well? Thank you.

image

@adamfisher
Copy link

Wow thank you but I am still having an issue with it returning any data once I add the filter.

I'm waiting on issue #329 to be resolved so I can debug with Fiddler. How does it layout the header exactly? I am expecting it to output this:

Authorization: Bearer sdjfniwebwdfmsdkf.sdfnuwehefunwienfwef.wefuweiufwenfwenf

I am integrating with the JwtForWebApi library and I would like the Authentication token field to appear any time I decorate [Authorize] on a controller or action method. This is what I have so far.

public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
    var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
    var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Instance).Any(filter => filter is IAuthorizationFilter);
    var authorizationRequired = apiDescription.GetControllerAndActionAttributes<AuthorizeAttribute>().Any();

    if (isAuthorized && authorizationRequired)
    {
        operation.parameters.Add(new Parameter
        {
            name = "Authorization Token",
            @in = "header",
            description = "JWT security token obtained from the service method Login.",
            required = true,
            type = "string"
        });
    }
}

@jskrepnek
Copy link

@adamfisher

Did you register the filter?, like so

httpConfig
.EnableSwagger("docs/{apiVersion}", config => {
config.SingleApiVersion("v1", "api");
config.OperationFilter<AddAuthorizationHeaderParameterOperationFilter>();
})

If you did, when you step through the Apply method, are you seeing expected values for isAuthorized and authorizationRequired? You're determining this differently compared to the solution I shared above.

Also, the 'name' of the parameter should be just 'Authorization' rather than 'Authorization Token'.

@MarwaAhmed
Copy link

Yes, correction: 'Authorization Basic' and 'Authorization: Basic' are not valid HTTP header fields names.
This work out if:

 name = "Authorization"

but in the swagger UI, the api's user could pass: basic or whatever the used token name.
here's mine:

image

@adamfisher
Copy link

That worked for me. Thanks guys!

@deepakvij
Copy link

Great post. Saved me a lot of time, thanks!!

@johnkors
Copy link

@domaindrivendev How's this going to work when we're using owin middleware to define how authorization works for our APIs? The [Authorize] attribute only says that it's in need of auth, not how it's done.

@Sandiejat
Copy link

@johnkors - Did you figure out a way to do that?
When I try the above solutions authorizationRequired is null in
var authorizationRequired = apiDescription.ActionDescriptor.GetCustomAttributes().Any();

@johnkors
Copy link

No,sorry. We document the auth process outside Swagger now.

@MrOnyancha
Copy link

I have failed to add the operation filter. any guidance please...

@hsfoggia
Copy link

hsfoggia commented Jun 7, 2018

In Vb.NET

Public Class AddAuthTokenHeaderParameter
Implements IOperationFilter

Public Sub Apply(operation As Operation, schemaRegistry As SchemaRegistry, apiDescription As ApiDescription) Implements IOperationFilter.Apply

    Dim filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline()
    Dim isAuthorized = filterPipeline.Select(Function(s) s.Instance).Any(Function(sc) sc.GetType().Equals(GetType(UnisyncAuthorizeAttribute)))

    Dim allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes(Of AllowAnonymousAttribute)().Any()

    If isAuthorized And (Not allowAnonymous) Then
        If operation.parameters Is Nothing Then
            operation.parameters = New List(Of Parameter)
        End If
        operation.parameters.Add(New Parameter With {
                .name = "Authorization",
                .in = "header",
                .description = "access token",
                .required = True,
                .type = "string"
            })
    End If

End Sub

End Class

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