Authorization header is not sent in swagger calls - spring

I am using following spring boot dependencies.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
I configured Authorization header for the rest endpoint like below.
#RestController
#Api(tags = "Welcome Controller", description = "Welcome API")
public class HomeController {
#ApiOperation(value = "Sent secret message", notes = "Sent secret message")
#ApiImplicitParams({
#ApiImplicitParam(name = "Authorization", value = "Access Token", required = false, allowEmptyValue = false, paramType = "header", dataTypeClass = String.class, example = "Bearer access_token") })
#GetMapping("/secret-message")
public Object tokenResponse() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return principal;
}
}
But when I opened the swagger and try to execute the rest end point with Bearer token, this Authorizaiton header is not sent as part of the request. How can we resolve this?
References
https://github.com/tiangolo/fastapi/issues/1037
https://github.com/tiangolo/fastapi/issues/612

This problem is with the latest version of swagger. But things are working fine with swagger 2.9.2
<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>

Related

swagger UI doesn't show apis while all configuration seems to be right

I have a springboot helloword project, the structure isstructure of project
and my swaggerConfig is
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//.enable(false)
.select()
.apis(RequestHandlerSelectors.basePackage("org/jayden/swaggertest/controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SpringBoot and Swagger2")
.description("desc")
.termsOfServiceUrl("http://localhost:8080/")
.version("1.0.0")
.build();
}
}
My controller is:
#RestController
#RequestMapping("/user")
#Api(value = "testApi", tags = "test")
public class UserController {
/**
* #param
* #return
*/
#PostMapping(value = "/save")
#ApiImplicitParam(name = "user", value = "addUser")
#ApiOperation(value = "addUser", notes = "addUserByParm")
public String saveUser(){
return "added";
}
I use porm.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
Could you please tell me what mistake I've made.
I've got the wrong message from swagger-ui:
wrong message from swagger-ui
I've got wrong message from console in chrome:
wrong in chrome console
This is my first time to ask question on stackOverflow, sorry for any unclear descriptions. Thank you guys!
You can try
RequestHandlerSelectors.basePackage("org/jayden/swaggertest/controller")
instead of
RequestHandlerSelectors.basePackage("org.jayden.swaggertest.controller")

Unable to figure out how to work with Spring Data REST endpoints

I am getting this as response:
{
"timestamp": "2020-04-15T06:39:29.174+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/api/users"
}
when I am sending GET request at:
http://localhost:8080/api/users
endpoint with following #RepositoryRestResource:
#RepositoryRestResource(collectionResourceRel = "api/users", path = "api/users")
public interface UserRestRepository extends CrudRepository<User, Integer> {
}
with dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Question is what is missing in my configuration above? Is there any other setting for working with Spring Data REST?
I am totally new to the world of Spring Data REST.
All of your configurations looks OK, but your issue may be resolved by appending just:
# ************************************
# For Spring Data REST Base Path #
#*************************************
spring.data.rest.base-path=/api
Into your application.properties file.
There is no need of adding api/ or /api/ in collectionResourceRel and path just:
#RepositoryRestResource(collectionResourceRel = "users", path = "users")
Is enough. Hope it resolves your issue.
Happy Coding!

Getting 415 Unsupported Media Type in spring boot

Method in controller
#RequestMapping(value = "/reactEmployee", method = RequestMethod.POST, consumes = "application/json")
public String addEmployeereact(#RequestBody EmployeeEntity employeeEntity)
{
employeeManager.addEmployee(employeeEntity);
return "redirect:/";
}
Json input from Postman
Json input and 415 error in Postman
After looking at github link I found that jackson needs to be specified in pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.12.4</version>
</dependency>

Forward to JSP within Spring Controller after form submission

Using Spring #Controller, #RequestMapping and #ModelAttribute, I'd like to achieve a basic form submission flow in which the user is forwarded to a new JSP with attributes set. Spring provides different ways to achieve this, but I have received various errors.
Example 1
Based on tutorial: https://www.baeldung.com/spring-mvc-form-tutorial
form.html
<form action="/submitForm" method="POST">
<input type="text"id="field1" name="field1">
<!-- other input fields -->
<button type="submit">Submit</button>
</form>
success.jsp
<p>Thanks for signing up ${userName}!!</p>
MyController.java
#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String post(#ModelAttribute SignupRequest request, ModelMap model){
// At this point, the SignupRequest is populated correctly
model.addAttribute("userName", request.getUserName());
return "success";
}
}
Results
Using return "success" - the result is HTTP 404 Not Found
Using return "success.jsp", the result is HTTP 405 Request method
'POST' not supported
Using return "redirect:/success.jsp", the client is redirected,
but attributes are not set, and ${userName} is visible.
Example 2
Based on the accepted answer here: Redirect after POST method in spring MVC
MyController.java
#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ModelAndView post(#ModelAttribute SignupRequest request){
// At this point, the SignupRequest is populated correctly
ModelAndView mAV = new ModelAndView("redirect:/success.jsp");
mAV.addObject("userName", request.getUserName());
return mAV;
}
}
Result
the client is redirected, but attributes are not set, and ${userName} is visible.
What is the correct way to do this?
Thanks!
EDIT
Additional details
Using SpringBoot with embedded Tomcat. JSP file located in src>main>resources>public. The raw JSP is being served. I believe the project is not treating JSP as it should. Adding POM deps.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
#Controller
public class MyController{
#RequestMapping(
value = "/submitForm",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public RedirectView post(#ModelAttribute SignupRequest request, RedirectAttributes ra){
// At this point, the SignupRequest is populated correctly
RedirectView rw = new RedirectView();
rw.setUrl("success.jsp");
ra.addFlashAttribute("userName", request.getUserName());
return rw;
}
}

How document an API that produces a file (pdf) for download on Swagger?

I'm trying to discover some way to document an API that returns a PDF (or any other file) to download.
Using Spring, my Rest resource is like this:
#Override
#GetMapping(produces = "application/pdf")
public ResponseEntity<InputStreamResource> find(
#PathVariable long id
) {
Result result = service.find(id);
HttpHeaders headers = disableCache();
return ResponseEntity
.ok()
.headers(headers)
.contentLength(result.getSize())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(new InputStreamResource(result.getFileInputStream()));
}
This works very well to download the file. But I don't know the good practice to document the response using Swagger.
Actually, I tried that with Swagger annotations:
#ApiOperation(value = "Some description")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Success.")
})
#ResponseStatus(HttpStatus.OK)
#GetMapping(produces = "application/pdf")
ResponseEntity<InputStreamResource> find(
#PathVariable long id
);
But the Swagger returns the content of InputStreamResource as Json on Swagger-ui, what is not the result.
How represent a file download on the response for Swagger?
Let try to update your code like this:
Update headers:
headers.add("Content-Type", "application/pdf");
headers.add("Content-Disposition", "attachment; filename=report.pdf");
Use this annotation:
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Success.", response = byte.class)
})
Update the pom:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
Hope it helps.
The annotations were ignored, but this worked for me:
TypeResolver typeResolver = new TypeResolver();
new Docket(DocumentationType.OAS_30)
.alternateTypeRules(AlternateTypeRules.newRule(
typeResolver.resolve(ResponseEntity.class, InputStreamResource.class),
typeResolver.resolve(Byte.class),
DIRECT_SUBSTITUTION_RULE_ORDER));

Resources