Abhishek
Abhishek

Reputation: 33

Basic Authentication using Swagger UI

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

Upvotes: 3

Views: 24019

Answers (5)

Devil
Devil

Reputation: 111

Ref - Spring Boot 3 + Basic Authentication + Swagger
Faced a similar problem for Spring Boot3 + Basic Authentication Example. Had to make following changes.
1. Whitelist Swagger URL.
Create OpenAPI bean specifiying that we will be making use of Basic Authentication SecurityScheme for swagger as follows -

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("JavaInUse Authentication Service"))             
                .addSecurityItem(new SecurityRequirement().addList("JavaInUseSecurityScheme"))
                .components(new Components().addSecuritySchemes("JavaInUseSecurityScheme", new SecurityScheme()
                        .name("JavaInUseSecurityScheme").type(SecurityScheme.Type.HTTP).scheme("basic")));
    }
}

Upvotes: 0

Prathamesh Beri
Prathamesh Beri

Reputation: 141

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

Upvotes: 2

evigis
evigis

Reputation: 153

Those who want to basic auth only for endpoints should do everything what @Sifis wrote but need to change antMatchers as:

public class SecurityConfig extends WebSecurityConfigurerAdapter{

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

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

    }
}

Upvotes: 0

Sifis
Sifis

Reputation: 653

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();

    }
}

Upvotes: 9

JetBrains
JetBrains

Reputation: 476

Use a following dependency in build.gradle to enable a security:

"org.springframework.boot:spring-boot-starter-security"


In application.properties you can define your own username and password using:

spring.security.user.name=user
spring.security.user.password=password

Upvotes: 0

Related Questions