'Swagger UI being blocked by Spring Security
I am trying to implement spring security with JWT token, I am trying to achieve authentication with method level authorization
My configuration looks like this SwaggerConfig.java
@Configuration
@PropertySource({"classpath:application.properties"})
@EnableSwagger2
@EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer {
@Autowired
private Environment env;
@Value("${swagger.enable:false}")
private Boolean isEnabled;
@Bean
public Docket swaggerBean() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(isEnabled)
.select()
.apis(RequestHandlerSelectors.basePackage("com.my.packageapi.v1"))
.paths(PathSelectors.any())
.build()
.apiInfo(getApiInfo())
.tags(new Tag(env.getProperty("swagger.display.project.name"), env.getProperty("swagger.display.project.description")));
}
private ApiInfo getApiInfo() {
return new ApiInfoBuilder()
.title(env.getProperty("swagger.display.page.title"))
.description(env.getProperty("swagger.display.module.description"))
.version(env.getProperty("swagger.display.version"))
.build();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/media/**", "/assets/**", "/static/**", "/images/**", "/css/**", "/js/**")
.addResourceLocations("classpath:/assets/", "classpath:/static/media/", "classpath:/static/images/",
"classpath:/static/css/", "classpath:/static/js/", "classpath:js/");
registry.addResourceHandler("/dist/**").addResourceLocations("/dist/");
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
//registry.addResourceHandler(contextPath+"/dist/**").addResourceLocations(contextPath+"/dist/");
//registry.addResourceHandler(contextPath+"/static/**").addResourceLocations(contextPath+"/static/");
}
}
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(securedEnabled = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Qualifier("userService")
@Autowired
private UserDetailsService userDetailsService;
@Qualifier("ApplicationAuthenticationManager")
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtAuthenticationFilter authenticationFilter;
@Autowired
private PasswordEncoder encoder;
@Override
public AuthenticationManager authenticationManagerBean() {
return authenticationManager;
}
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/swagger**");
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers(
"/token/**",
"/configuration/ui",
"/swagger-resources/*",
"/configuration/security",
"/webjars/*",
"/swagger-ui*",
"/favicon*").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/*",
"/configuration/security",
"/swagger-ui*",
"/swagger-ui.html/*",
"/webjars/*");
}
JWTAthenticationFilter.java
@Configuration
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Qualifier("userService")
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private TokenProvider jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
String username = null;
String authToken = null;
if (header != null && header.startsWith(TOKEN_PREFIX)) {
authToken = header.replace(TOKEN_PREFIX, "");
try {
username = jwtTokenUtil.getUsernameFromToken(authToken);
} catch (IllegalArgumentException e) {
logger.error("an error occurred during getting username from token", e);
} catch (ExpiredJwtException e) {
logger.warn("the token is expired and not valid anymore", e);
} catch (SignatureException e) {
logger.error("Authentication Failed. Username or Password not valid.");
}
} else {
logger.warn("couldn't find bearer string, will ignore the header");
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = jwtTokenUtil.getAuthentication(authToken, SecurityContextHolder.getContext().getAuthentication(), userDetails);
//UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")));
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(req));
logger.info("authenticated user " + username + ", setting security context");
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
System.err.println("Filtering " + req.getContextPath() + " " + req.getRequestURL());
chain.doFilter(req, res);
}
}
JWTAthenticationEntryPoint.java
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
I have followed it from here
Already tried many of solution, listing few below
Swagger UI empty and gives 403
If you spot any other improvements, please feel free to drop your comments. Every bit of help is appreciated.
Solution 1:[1]
In the ant matchers part add .antMatchers("/v2/api-docs", "/configuration/**", "/swagger*/**", "/webjars/**").permitAll()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | dcatano |