Reputation: 33
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
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
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
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
Reputation: 653
One option is to use the browser pop up authorization.
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.
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.
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
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