Basic Authentication using Swagger UI

12,332

Solution 1

One option is to use the browser pop up authorization.

  1. When you enable basic auth for your spring boot app, swagger ui will automatically use the browser's pop up window in order to use it for basic auth. This means that the browser will keep the credentials for making requests just like when you trying to access a secured GET endpoint until you close it.

Now, let's say you DON'T want to use the above and want swagger-ui for basic authentication as you say, you have to enable auth functionality on swagger-ui and optionally add security exception when accessing swagger-ui url.

  1. To enable the basic auth functionality to swagger UI (with the "Authorize button" in UI) you have to set security Context and Scheme to your Swagger Docket (This is a simplified version):

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig implements WebMvcConfigurer{
    
        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(PathSelectors.any())
                    .build()
                    .securityContexts(Arrays.asList(securityContext()))
                    .securitySchemes(Arrays.asList(basicAuthScheme()));
       }
    
        private SecurityContext securityContext() {
            return SecurityContext.builder()
                    .securityReferences(Arrays.asList(basicAuthReference()))
                    .forPaths(PathSelectors.ant("/api/v1/**"))
                    .build();
        }
    
        private SecurityScheme basicAuthScheme() {
            return new BasicAuth("basicAuth");
        }
    
        private SecurityReference basicAuthReference() {
            return new SecurityReference("basicAuth", new AuthorizationScope[0]);
        }
    
    }
    

This enables the authorization button in ui. enter image description here

Now you probably want for your users to access the swagger-ui freely and use this button for authorization. To do this you have to exempt swagger for app's basic auth. Part of this configuration is Security config and you have to add following code:

public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {

            http
                .httpBasic()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)   
                .and().authorizeRequests()
                .antMatchers(
                        "/", "/csrf", 
                        "/v2/api-docs", 
                        "/swagger-resources/**",
                        "/swagger-ui.html",
                        "/webjars/**"
                        ).permitAll()
                .anyRequest().authenticated();

    }
}

Solution 2

A similar problem I was facing was that when using springfox documentation with Swagger OAS 3.0, the "Authenticate" button would not appear on the swagger UI.

Turns out there was a bug created for this very issue-

https://github.com/springfox/springfox/issues/3518

The core of the problem- Class BasicAuth is deprecated.

The solution as found in the bug report above is to use HttpAuthenticationScheme instead to define the SecurityScheme object.

The Docket configuration then looks like so-

return new Docket(DocumentationType.OAS_30)
                .groupName("Your_Group_name")
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mypackage"))
                .paths(PathSelectors.regex("/.*"))
                .build().securitySchemes(Arrays.asList(HttpAuthenticationScheme.BASIC_AUTH_BUILDER.name("basicAuth").description("Basic authorization").build())) 
                .securityContexts(); //define security context for your app here
Share:
12,332

Related videos on Youtube

Abhishek
Author by

Abhishek

Updated on May 25, 2022

Comments

  • Abhishek
    Abhishek almost 2 years

    I am trying to develop a spring-boot based rest API service with API documentation through Swagger UI. I want to enable basic authentication via the swagger UI so that the user can only run the API's once he/she authenticates using the Authorize button on swagger UI (by which a "authorization: Basic XYZ header is added to the API Call

    At the front end (in the .json file for the Swagger UI I have added basic authentication for all the APIs using the following code (as per the documentation):

    "securityDefinitions": {
            "basic_auth": {
                "type": "basic"
            }
        },
        "security": [
            {
                "basic_auth": []
            }
        ]
    

    How should I implement the backend logic for the use case mentioned above (user can only run the API's once he/she authenticates using the Authorize button on swagger UI and it otherwise shows a 401 Error on running the API)

    Some documentation or sample code for the same would be helpful

    • chrylis -cautiouslyoptimistic-
      chrylis -cautiouslyoptimistic- over 4 years
      If you're using HTTP Basic, there is no "authorize" step. The browser asks the user for credentials and passes them in.
    • Abhishek
      Abhishek over 4 years
      Yes, and with the credentials, at the backend of the application I can introduce access control by extending a WebSecurityConfigurerAdapter class and overriding the configureGlobal(AuthenticationManagerBuilder auth) via jdbcAuthentication to check for user and their authorities and similarly override configure(HttpSecurity) to allow only authenticated and authorized users to access urls, right?
    • chrylis -cautiouslyoptimistic-
      chrylis -cautiouslyoptimistic- over 4 years
      Yes, you could. Note that Basic authentication has a number of drawbacks, so it's fine to use for testing and learning but you should really use something like OAuth2 for real applications. (Also, it's very common in Boot applications for the entire application to be a REST service that is 100% protected, and in that case the default Boot configuration is to protect everything.)
    • Abhishek
      Abhishek over 4 years
      Yes, this is currently for testing and learning. For now, what I want to do is enable access to my API UI to all, but only allow authenticated users to be able to call the APIs. In my implementation of the logic I specified above, as you said, spring-security is securing the entire application which is not what I need. I have tried playing around with the configure(HttpSecurity) parameters but it doesn't seem to work
  • Abhishek
    Abhishek over 4 years
    From what I understand, this makes it accessible only for a single user. What if I need to extend this for multiple users?
  • JetBrains
    JetBrains over 4 years
    You can use keycloak to manage users. There is a spring boot starter for Keycloak and it is easy to use. Here is a website: keycloak.org Here is a good tutorial for Keycloak with Spring Boot: baeldung.com/spring-boot-keycloak
  • Abhishek
    Abhishek over 4 years
    Thanks @Sifls. I have indeed followed the second part. I second what you said about making changes in the configure(HttpSecurity http) and configuring the antMatchers to secure the API's that I needed to secure. Also, another important point which you touched upon, and I think is well emphasised is using the STATELESS session creation policy. Thanks for your help