Basic Authentication using Swagger UI
Solution 1
One option is to use the browser pop up authorization.
- 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.
-
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();
}
}
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
Related videos on Youtube
Abhishek
Updated on May 25, 2022Comments
-
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 CallAt 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- over 4 yearsIf you're using HTTP Basic, there is no "authorize" step. The browser asks the user for credentials and passes them in.
-
Abhishek over 4 yearsYes, and with the credentials, at the backend of the application I can introduce access control by extending a
WebSecurityConfigurerAdapter
class and overriding theconfigureGlobal(AuthenticationManagerBuilder auth)
viajdbcAuthentication
to check for user and their authorities and similarly overrideconfigure(HttpSecurity)
to allow only authenticated and authorized users to access urls, right? -
chrylis -cautiouslyoptimistic- over 4 yearsYes, 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 over 4 yearsYes, 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 over 4 yearsFrom what I understand, this makes it accessible only for a single user. What if I need to extend this for multiple users?
-
JetBrains over 4 yearsYou 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 over 4 yearsThanks @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