'Separate authentication for Swagger and API
I have the SecurityConfig.java like below
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
AuthenticationEntryPointJwt authenticationEntryPointJwt;
@Autowired
TokenProcessor tokenProcessor;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/v2/api-docs").authenticated()
.antMatchers("/swagger-ui.html").authenticated()
.antMatchers("/swagger-ui/index.html").authenticated()
.antMatchers("/swagger-ui/").authenticated()
.antMatchers("/**/signup", "/**/verify", "/**/login")
.permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPointJwt).and()
.addFilterBefore(new JwtAuthFilter(tokenProcessor), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.csrf().disable();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("USER");
}
}
The JWTAuthFilter.java
public class JwtAuthFilter extends GenericFilterBean {
private UserIdentityTokenProcessor cognitoIdTokenProcessor;
public JwtAuthFilter(UserIdentityTokenProcessor cognitoIdTokenProcessor) {
this.cognitoIdTokenProcessor = cognitoIdTokenProcessor;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
try {
Authentication authentication = this.cognitoIdTokenProcessor.authenticate((HttpServletRequest) request);
if (authentication != null) {
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
SecurityContextHolder.clearContext();
}
filterChain.doFilter(request, response);
}
}
And the AuthenticationEntryPointJwt.java
public class AuthenticationEntryPointJwt implements AuthenticationEntryPoint {
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
@Override
public void commence(HttpServletRequest request, HttpServletResponse httpServletResponse, AuthenticationException authException) throws IOException, ServletException {
log.warn("Unauthorized request {}", request.getRequestURI());
ResponseDTO<Object> response = new ResponseDTO<Object>(false, "Authentication failed: bad credentials",
null, "UNAUTHORIZED", null);
String responseJsonString = GSON.toJson(response);
PrintWriter out = httpServletResponse.getWriter();
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
out.print(responseJsonString);
out.flush();
}
}
My expectation is that:
- When the user access to the swagger-ui (ex: http://localhost:8080/user/swagger-ui/index.html), there is the pop-up appear to enter the username/password which has defined in SecurityConfig.java
- After login successfully, when user try to perform the api, they need to add the Bearer token into the header. (token verification)
The current problem:
- If I configure like some classes above, when I access to the swagger-ui, it will show the error:
{"status":false, "message":"Authentication failed: bad credentials","messageCode":null,"errorCode":"UNAUTHORIZED","data":null}
It means the token verification already applied for the swagger-ui as well. I have tried some ways but I just achieve one way like you keep the token verification but missing the login pop-up.
How could I reach my expectation? (swagger-ui need to show login pop-up and calling api need to process token verification)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
