Add Swagger Basic AUTH to Spring Boot App
Solution 1
You should use the .authenticated()
instead of .permitAll()
:
.authorizeRequests()
.antMatchers("/swagger-resources/*", "*.html", "/api/v1/swagger.json")
.hasRole("SWAGGER")
.anyRequest()
.authenticated()
This will:
Restrict access to all resources matching
/swagger-resources/*
,*.html
and/api/v1/swagger.json
Allow unauthenticated access to all other resources
For clarification on why your configuration doesn't work, it's because you're not reading spring-security like you should be reading it.
Your old configuration reads like this:
.authorizeRequests() // allow requests
.antMatchers(...) // that matches this
.hasAuthority("SWAGGER") // with SWAGGER authority
.anyRequest() // All requests above
.permitAll() // grant full access
In other words, you're granting full access to users with the SWAGGER
authority, but what you've neglected is that by default, they already have access to it. To be more precise, everybody has access to it unless you specify otherwise.
By using .authenticated()
. you're telling Spring that you want all requests matched to be restricted to people with the proper role
or authority
.
New configuration:
.authorizeRequests() // allow requests
.antMatchers(...) // that matches this
.hasRole("SWAGGER") // with role SWAGGER
.anyRequest() // all requests above
.authenticated() // needs authentication
Update
Regarding your issue with /swagger-resources
, /swagger-resources/configuration/security
and swagger-resources/configuration/ui
returning 401:
You should replace /swagger-resources/*
for /swagger-resources/**
.
Update 2
Add the following at the end of your configuration to permit all non-matched requests:
.authorizeRequests()
.anyRequest()
.permitAll();
Solution 2
You could do something like below
Swagger
The code for swagger is like below.
private List<SecurityScheme> basicScheme() {
List<SecurityScheme> schemeList = new ArrayList<>();
schemeList.add(new BasicAuth("basicAuth"));
return schemeList;
}
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.
.
.
.securitySchemes(basicScheme());
}
Security Config
For the security config
public void configureGlobal(final AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("USER")
.password("PASSWORD")
.roles("ADMIN");
}
.
.
.
@Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.anyRequest().authenticated().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().httpBasic();
}
.
.
.
@Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/webjars/**",
"/configuration/security",
"/swagger-ui.html");
}
Controllers
Below passes the authorization to the methods using swagger.
@PutMapping("/registration/{id}")
@ApiOperation(value = "Update registration detail",
authorizations = { @Authorization(value="basicAuth") })
public ResponseEntity<RegistrationModel> updateRegistration(
POM
and in your pom.xml, you will be needing:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
That's basically it.
Solution 3
Your configuration is strange. You can try something like that:
public static void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.antMatcher("/swagger-ui.html")
.authorizeRequests()
.anyRequest().hasAnyRole("SWAGGER")
.and()
.httpBasic();
}
This ensures authorization to swagger-ui.html
path (with SWAGGER
role).
Cortlendt
Updated on June 21, 2022Comments
-
Cortlendt almost 2 years
Requirements:
- Spring Boot application with Springfox
- Add BASIC authentication to Swagger
- Pass on all other requests
Code: implemented
@EnableWebSecurity @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/swagger-resources/*", "*.html", "/api/v1/swagger.json") .hasAuthority("SWAGGER") .anyRequest().permitAll() .and() .httpBasic() .and() .csrf().disable(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("admin").password("admin").authorities("SWAGGER"); } }
This code however does not work - you can freely browse /swagger-ui.html#/ without any authentcation.
Question is - why BASIC auth and user do not apply to swagger ui endpoint?
-
Glim about 6 yearsreally? In my case I use it specifically to a restricted page. Try add
security.basic.enabled=true
in your application.properties -
Michlis about 6 yearsWhat if you try to match by
"/swagger-ui*"
? I remember there were some issues with antMatchers and page extensions, since they evaluate againstservletPath
+pathInfo
(see AntPathRequestMatcher docs) -
Cortlendt about 6 yearsI've started getting "Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. The base url is the root of where all the swagger resources are served." in browser. It should be something with ant matcher?
-
Cortlendt about 6 yearsIn addition, authentication works BUT swagger UI does not render. When swagger-ui.html loads, it invokes js script, which does 3 requests /swagger-resources, /swagger-resources/configuration/security, swagger-resources/configuration/ui. All of them result in 401. They do have a matcher and do open in browser. Please help.
-
Cortlendt about 6 years/swagger-resources/* is not the case of 401, i think it is a bug in js, which does not provide AUTHORIZATION header. I've rolled back to different version and the header is provided.
-
TwiN about 6 years@Cortlendt are you sure?
/swagger-resources/*
should not match/swagger-resources/configuration/security
and/swagger-resources/configuration/security
whereas/swagger-resources/**
should. -
Cortlendt about 6 yearsI'm using 2.2.6.1 version of springfox and it works. However, I have other problem - all other requests DO require basic auth now.
-
Cortlendt about 6 yearsfixed by adding additional authorizeRequests fluent invocation in the end. .authorizeRequests().anyRequest().permitAll();
-
TwiN about 6 years@Cortlendt I updated my answer with that the moment you wrote that :P