In my application, I am adding swagger-ui but it's not showing controller apis. When I checked in developer console, it's showing that localhost:9000/
and localhost:9000/csrf
apis getting failed.
Below is my Security config:
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
@Bean
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider authenticationProvider =
new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl,ldapBase);
authenticationProvider.setConvertSubErrorCodesToExceptions(true);
authenticationProvider.setUseAuthenticationRequestCredentials(true);
authenticationProvider.setSearchFilter("(sAMAccountName={1})");
return authenticationProvider;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf()
.disable()
.exceptionHandling().authenticationEntryPoint(jwtUnAuthorizedResponseAuthenticationEntryPoint).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**").permitAll()
.anyRequest().authenticated();
httpSecurity
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
httpSecurity
.headers()
.frameOptions().sameOrigin() //H2 Console Needs this setting
.cacheControl(); //disable caching
}
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity
.ignoring()
.antMatchers(
HttpMethod.POST,
authenticationPath
)
.antMatchers(HttpMethod.OPTIONS, "/**")
.and()
.ignoring()
.antMatchers(
HttpMethod.GET,
"/" //Other Stuff You want to Ignore
)
.and()
.ignoring()
.antMatchers("/h2-console/**/**");//Should not be in Production!
}
SwaggerConfig:
public static final String DEFAULT_INCLUDE_PATTERN = "/deployer/*.*";
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.org.deployer.controller"))
.paths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN)).build().apiInfo(metaData())
.securityContexts(Lists.newArrayList(securityContext()))
.securitySchemes(Lists.newArrayList(apiKey()))
.useDefaultResponseMessages(false);
}
private ApiKey apiKey() {
return new ApiKey("JWT", AUTHORIZATION_HEADER, "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN))
.build();
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope
= new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Lists.newArrayList(
new SecurityReference("JWT", authorizationScopes));
}
Response for /v2/api-docs api:
{
"swagger": "2.0",
"info": {
"description": "deployment Tool ",
"version": "1.0",
"title": " api",
"termsOfService": "Terms of service",
"contact": {
"name": "Support Team"
},
"license": {
}
},
"host": "localhost:9000",
"basePath": "/",
"securityDefinitions": {
"JWT": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}
Controller:
package com.org.deployer.controller;
@RestController
@CrossOrigin(origins = "http://localhost:4200")
@Api(value = "package operations", description = "Operations pertaining to Package Schedule")
public class PackageScheduleController {
private static final Logger logger = LoggerFactory.getLogger(PackageScheduleController.class);
@Autowired
PackageScheduleService packageScheduleService;
@PostMapping("/schedule")
@ApiOperation(value = "This method is used to get the clients.")
public PackageScheduleResponse schedule(@RequestBody PackageScheduleRequest packageScheduleRequest){
try{
logger.info("Schedule Request received for {}",packageScheduleRequest.getName());
System.out.println(packageScheduleRequest.getScheduleTime().toLocalTime());
return packageScheduleService.schedule(packageScheduleRequest);
}
catch(Exception e){
logger.error("Exception occured",e);
throw new RuntimeException("Some Error Occured");
}
}
@GetMapping("/view-schedule")
public List<PackageScheduleDto> schedule(){
try{
logger.info("Request received for fetching upcoming schedule jobs");
return packageScheduleService.fetchAllScheudules();
}
catch(Exception e){
logger.error("Exception occured",e);
throw new RuntimeException("Some Error Occured");
}
}
}
By Seeing I can understand that it's related csrf configuration but not sure how to solve it.
CodePudding user response:
The calls to localhost:9000
and localhost:9000/csrf
are an attempt by Springfox to retrieve a csrf token. Even if they fail, Springfox should still work. If you don't like those calls, you can disable them by adding the following configuration:
private SecurityContext securityContext() {
return SecurityConfigurationBuilder.builder()
// ...
.enableCsrfSupport(false) // Add this
.build();
}
However, the problem is that your controller endpoints do not match the pattern you configured (/deployer/*.*
). Due to this, they aren't included in Springfox.
To fix this, you can change the pattern (DEFAULT_INCLUDE_PATTERN
) or change the path selector to PathSelectors.any()
:
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
// ...
.paths(PathSelectors.any()) // Change this
.build()
// ...
}
Don't forget to change this in your SecurityContext
as well.