Spring boot rest api not failed in case of invalid Endpoint - spring

I am writing a RESTful web services using spring boot. I am using jwt bearer token for authentication an authorisation.
Below is my RestController
#RestController("api/v1/users")
public class UserController {
#Autowired
UserService userService;
#PostMapping
public User saveUser(#RequestBody User user) {
return userService.saveUser(user);
}
#GetMapping
public List<User> getUsers(#RequestParam(required = false) String pageNumber, String pageSize, String role, String status) {
return userService.findAll(pageNumber, pageSize, role, status);
}
}
When I hit the api with request-url
http://localhost:8080/api/v1/users?pageNumber=0&pageSize=6&role=admin
Its work perfectly
but if I change the url endpoint to some invalid endpoint like
http://localhost:8080/api/v1/hhh?pageNumber=0&pageSize=6&role=admin
It still returning same results as per 1st correct endpoint.
Below are some logs statements from springframework debug logging
Checking match of request : '/api/v1/hhh'; against
'/api/test/secureTest'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against 'api/authenticate'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/users/me'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/student'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/faculty'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/admin'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/api/v1/hhh'; against '/api/v1/users'
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.s.w.a.i.FilterSecurityInterceptor : Public object -
authentication not attempted
2019-12-28 19:16:47.601 DEBUG 5591 --- [nio-8080-exec-5]
o.s.security.web.FilterChainProxy :
/api/v1/hhh?pageNumber=0&pageSize=6&role=admin reached end of
additional filter chain; proceeding with original chain
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
o.s.web.servlet.DispatcherServlet : GET
"/api/v1/hhh?pageNumber=0&pageSize=6&role=admin", parameters={masked},
headers={masked} in DispatcherServlet 'dispatcherServlet'
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance
of singleton bean 'api/v1/users'
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public
java.util.List
com.asset.app.user.UserController.getUsers(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
2019-12-28 19:16:47.602 TRACE 5591 --- [nio-8080-exec-5]
.w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [0, 6, admin,
null]
I feel Spring cache the endpoint url and used if in case of no match found
Any Idea how to stop this?

if you read the api documentation for #RestController
You see that the annotation constructor takes in a value that is described as:
The value may indicate a suggestion for a logical component name, to
be turned into a Spring bean in case of an autodetected component.
So it is used to set a name for the Bean that vill be created.
It is not used to set a url-mapping like you have done.
#RestController("api/v1/users")
You need to annotate your class with #RequestMapping and also add mappings to the #PostMapping and #GetMapping.
#RestController
#RequestMapping("/api/v1") // Add request mapping
public class FooBar {
#PostMapping("/users") // Add mapping here
public User bar() {
...
}
#GetMapping("/users") // Add mapping here
public List<User> foo() {
...
}
}

Related

How to handle custom exceptions thrown by a filter in Spring Security

I am new to Spring Security.
I have a piece of code where I check if an Authorization header is passed in a request and I throw an exception if it's missing.
public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String BEARER = "Bearer";
public TokenAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
super(requiresAuthenticationRequestMatcher);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String username = request.getParameter("username");
String authorization = request.getHeader("AUTHORIZATION");
if (!request.getRequestURI().equals(UniversalConstants.LOGIN_PATH)) {
if (authorization == null || authorization.length() == 0 || !authorization.startsWith(BEARER)) {
throw new InvalidCredentialsException("Missing authentication token"); //<-----------------
}
}
String password = request.getParameter("password");
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username, password));
}
I am targeting to handle all exceptions globally so I'm using #ControllerAdvice.
Note: I know that #ControllerAdvice will not work for exceptions thrown outside of Controllers from this and this, so I have also followed the suggestions in these links.
RestAuthenticationEntryPoint.java
#Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
public RestAuthenticationEntryPoint() {
System.out.println("RestAuthenticationEntryPoint");
}
#Autowired
#Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
resolver.resolveException(request, response, null, authException);
}
}
This is how I configure the authenticationEntryPoint:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(new RestAuthenticationEntryPoint()).and().cors().and().csrf().disable().exceptionHandling().defaultAuthenticationEntryPointFor(new RestAuthenticationEntryPoint(), PROTECTED_URLS)
.and().authenticationProvider(customAuthenticationProvider())
.addFilterBefore(tokenAuthenticationFilter(), AnonymousAuthenticationFilter.class).authorizeRequests()
.requestMatchers(PROTECTED_URLS).authenticated().and().formLogin().disable().httpBasic().disable();
}
CustomExceptionHandler.java
#ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler({InvalidCredentialsException.class, AuthenticationException.class})
public ResponseEntity<ErrorResponse> handleUnauthorizedError(InvalidCredentialsException e, WebRequest request) {
String errorMessage = e.getLocalizedMessage();
ErrorResponse errorResponse = new ErrorResponse(errorMessage, null);
return new ResponseEntity<>(errorResponse, HttpStatus.UNAUTHORIZED);
}
}
InvalidCredentialsException.java
#ResponseStatus(HttpStatus.UNAUTHORIZED)
public class InvalidCredentialsException extends RuntimeException {
public InvalidCredentialsException(String errorMessage) {
super(errorMessage);
}
}
Upon debugging, I've found that the resolver.resolveException(...) in RestAuthenticationEntryPoint and the handleUnauthorizedError(..) in CustomExceptionHandler never get called.
I wish to handle throw new InvalidCredentialsException("Missing authentication token") in an elegant way and show a decent JSON output in the response.
Any help would be appreciated.
Edit: The stack trace
2021-05-20 17:41:29.985 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/public/**']
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user/hello'; against '/public/**'
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/error**']
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user/hello'; against '/error**'
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2021-05-20 17:41:29.986 DEBUG 24808 --- [nio-8181-exec-3] o.s.security.web.FilterChainProxy : /user/hello?username=user&password=user at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2021-05-20 17:41:29.988 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /user/hello' doesn't match 'DELETE /logout'
2021-05-20 17:41:29.988 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2021-05-20 17:41:29.988 DEBUG 24808 --- [nio-8181-exec-3] o.s.security.web.FilterChainProxy : /user/hello?username=user&password=user at position 6 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.s.HttpSessionRequestCache : saved request doesn't match
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.security.web.FilterChainProxy : /user/hello?username=user&password=user at position 7 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.security.web.FilterChainProxy : /user/hello?username=user&password=user at position 8 of 12 in additional filter chain; firing Filter: 'TokenAuthenticationFilter'
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/public/**']
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user/hello'; against '/public/**'
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2021-05-20 17:41:29.989 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2021-05-20 17:41:38.030 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#7fb6b4e0
2021-05-20 17:41:38.030 DEBUG 24808 --- [nio-8181-exec-3] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2021-05-20 17:41:38.030 DEBUG 24808 --- [nio-8181-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2021-05-20 17:41:38.033 ERROR 24808 --- [nio-8181-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
com.spring.fieldSecurity.Exceptions.InvalidCredentialsException: Missing authentication token
at com.spring.fieldSecurity.Service.TokenAuthenticationFilter.attemptAuthentication(TokenAuthenticationFilter.java:44) ~[classes/:na]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.3.3.RELEASE.jar:5.3.3.RELEASE]
.
. // more error trace here
.
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/public/**']
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/error'; against '/public/**'
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/error**']
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/error'; against '/error**'
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : matched
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.security.web.FilterChainProxy : /error?username=user&password=user has an empty filter list
2021-05-20 17:41:38.034 DEBUG 24808 --- [nio-8181-exec-3] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?username=user&password=user", parameters={masked}
2021-05-20 17:41:38.035 DEBUG 24808 --- [nio-8181-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2021-05-20 17:41:38.035 DEBUG 24808 --- [nio-8181-exec-3] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2021-05-20 17:41:38.724 DEBUG 24808 --- [nio-8181-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json] and supported [application/json, application/*+json, application/json, application/*+json]
2021-05-20 17:41:38.724 DEBUG 24808 --- [nio-8181-exec-3] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Thu May 20 17:41:38 IST 2021, status=500, error=Internal Server Error, message=, path=/us (truncated)...]
2021-05-20 17:41:38.726 DEBUG 24808 --- [nio-8181-exec-3] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2021-05-20 17:41:38.727 DEBUG 24808 --- [nio-8181-exec-3] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 500
Spring security has a filter which is called the ExceptionTranslationFilter which translates AccessDeniedException and AuthenticationException into responses. This filter catches these thrown exceptions in the spring security filter chain.
So if you want to return a custom exception, you could instead inherit from one of these classes instead of RuntimeException and add a custom message.
I just want to emphasis and it can never be said too many times:
Providing friendly error messages in production applications when it comes to authentication/authorization is in general bad practice from a security standpoint. These types of messages can benefit malicious actors, when trying out things so that they realize what they have done wrong and guide them in their hacking attempts.
Providing friendly messages in test environments may be okey, but make sure that they are disabled in production. In production all failed authentication attempts a recommendation is to return a 401 with no additional information. And in graphical clients, generalized error messages should be displayed for instance "failed to authenticate" with no given specifics.
Also:
Writing custom security as you have done is also in general bad practice. Spring security is battle tested with 100000 of applications running it in production environments. Writing a custom filter to handle token and passwords, is in general not needed. Spring security already has implemented filters to handle security and authentication using standards like BASIC authentication and TOKEN/JWT. If you implement a non standard login, one bug might expose your application to a huge risk.
Username and password authentication in spring
Oauth2 authentication in spring

Wrong Header of the API versioning of the Post Request does not come to handleNoHandlerFoundException?

I am using Spring Boot v2.1.7 + HATEOAS + Spring Rest + Spring Security. When consumer doesn't pass the correct Custom Header in the request, say passes X-Accept-Version=v5, it gives me below error.
Error:
2020-03-26 15:44:48.201 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : POST "/employee-catalog-api/reference-types", parameters={}
2020-03-26 15:44:48.216 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-03-26 15:44:48.217 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] .m.c.d.m.p.s.SAMLUserIdentityServiceImpl : Trying to get UserId from Security Context
2020-03-26 15:44:48.224 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#5c85f23b
2020-03-26 15:44:48.234 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-03-26 15:44:48.254 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-03-26 15:44:48.254 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2020-03-26 15:44:48.258 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2020-03-26 15:44:48.258 DEBUG [employee-service,14c23adbe2664530,14c23adbe2664530,false] 3608 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Code:
#PostMapping(path = "/employee-types", headers = {X-Accept-Version=v1})
public ResponseEntity<Integer> saveEmployeeType(#Valid #RequestBody EmployeeDto employeeDto) {
.....
......
......
return new ResponseEntity<>(HttpStatus.OK);
}
Why its not coming to handleNoHandlerFoundException of the #ControllerAdvice ?
#Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
...................
return handleExceptionInternal(ex, error, getHeaders(), HttpStatus.BAD_REQUEST, request);
}
I was able to solve this issue by taking a reference from : How to set default value of exported as false in rest resource spring data rest.
By adding below logic, it works greatly.
#Component
public class SpringRestConfiguration extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
config.setExposeRepositoryMethodsByDefault(false);
}
}

UTF-8 decoding in Spring Boot GET request to static resource

I have this #Bean redirecting requests to my Spring Boot backend.
#Bean
WebMvcConfigurer configurer () {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/data/static/images/**")
.addResourceLocations("file:" + System.getProperty("user.dir") + "/static/img/");
}
};
}
It works perfectly for URLs such as:
http://localhost:4200/data/static/images/champion/tiles/Ahri_0.jpg
But not for URLs such as:
http://localhost:4200/data/static/images/champion/tiles/Tahm%20Kench_0.jpg
The image is correctly shown in my Angular2 front end if the champion name does not contain any of: space, ampersand or single quote characters.
I ran a trace level logging debug and made both types of requests -- one with and without a "bad" character. Currently, it seems as if the backend searches for the correct file. However, it turns out that it claims it can't find it. I quintuple checked the file in my insanity, I know it is there and that the path printed is correct.
Here is an example log message:
2018-11-18 05:07:14.496 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#4d0bdef0] in DispatcherServlet with name 'dispatcherServlet'
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/data/static/images/champion/tiles/Tahm Kench_0.jpg] are [/data/static/images/**, /**]
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/data/static/images/champion/tiles/Tahm Kench_0.jpg] are {}
2018-11-18 05:07:14.497 DEBUG 9897 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/data/static/images/champion/tiles/Tahm Kench_0.jpg] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[URL [file:/home/nuradin/Development/Java/riot-api-interface/static/img/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#5b5b59]]] and 1 interceptor
2018-11-18 05:07:14.497 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#132f4851]
2018-11-18 05:07:14.497 TRACE 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Testing handler adapter [org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter#5b8d72dc]
2018-11-18 05:07:14.498 DEBUG 9897 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/data/static/images/champion/tiles/Tahm%20Kench_0.jpg] is: -1
2018-11-18 05:07:14.498 DEBUG 9897 --- [on(7)-127.0.0.1] sun.rmi.transport.tcp : RMI TCP Connection(7)-127.0.0.1: (port 34127) op = 82
2018-11-18 05:07:14.498 TRACE 9897 --- [nio-8080-exec-1] o.s.w.s.resource.PathResourceResolver : Resolving resource for request path "champion/tiles/Tahm Kench_0.jpg"
2018-11-18 05:07:14.498 TRACE 9897 --- [nio-8080-exec-1] o.s.w.s.resource.PathResourceResolver : Checking location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/img/]
EDIT: I've implemented the class in the accepted answer, and it's definitely working because I printed the resource name (after encoding the characters I had trouble with.) However, the result is still a 404 error.
Log is below. The champion/Aatrox2Epng bit is due to a println statement in the method #slimane posted below.
2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Testing handler adapter [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#465ac973]
2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Testing handler adapter [org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter#37df7ae5]
2018-11-18 05:56:40.509 DEBUG 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/data/static/images/champion/Aatrox.png] is: -1
2018-11-18 05:56:40.509 TRACE 12951 --- [nio-8080-exec-1] o.s.w.s.r.CachingResourceResolver : Resolving resource for request path "champion/Aatrox.png"
2018-11-18 05:56:40.510 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver : Resolving resource for request path "champion/Aatrox.png"
2018-11-18 05:56:40.510 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver : Checking location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/8.23.1/img]
champion/Aatrox2Epng
2018-11-18 05:56:40.511 TRACE 12951 --- [nio-8080-exec-1] o.e.r.c.EncodedPathResourceResolver : No match for location: URL [file:/home/nuradin/Development/Java/riot-api-interface/static/8.23.1/img]
2018-11-18 05:56:40.511 TRACE 12951 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : No matching resource found - returning 404
2018-11-18 05:56:40.511 DEBUG 12951 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
another EDIT -- sorry for the confusion, I changed the path because I thought paths with periods would work now.
#Bean
WebMvcConfigurer configurer () {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/data/static/images/**")
.addResourceLocations("file:" + System.getProperty("user.dir") + "/static/8.23.1/img")
.resourceChain(true)
.addResolver(encodedPathResourceResolver());
}
};
}
define your own PathResourceResolver as below:
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolver;
import java.io.IOException;
public class CustomPathResourceResolver extends PathResourceResolver implements ResourceResolver {
#Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
//fixes problems with whitespaces in url
resourcePath = resourcePath.replace(" ","%20");
return super.getResource(resourcePath, location);
}
}
and then register it in your configuration:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/data/static/images/**")
.addResourceLocations("file:" + System.getProperty("user.dir") + "/static/img/")
.resourceChain(true)
.addResolver(new CustomPathResourceResolver())
;
}
This fixed the Problem for me. Somehow the path was encoded 2 times.
This removes all URI encoding not just whitespaces.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("file:/Q:/Technik/")
.resourceChain(true)
.addResolver(new CustomPathResourceResolver());
}
public class CustomPathResourceResolver extends PathResourceResolver implements ResourceResolver {
#Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
//fixes problems with special chars in url
log.debug(resourcePath);
resourcePath = UriUtils.decode(resourcePath, "UTF-8");
log.debug(resourcePath);
resourcePath = UriUtils.decode(resourcePath, "UTF-8");
log.debug(resourcePath);
return super.getResource(resourcePath, location);
}
}

Spring security lead to error for PUT and POST request through Ajax

I have a small ajax request which is lead to exeption PUT http://localhost:8080/carwash/add 405 (Method Not Allowed). Can you explaim me where is a problem?
Ajax request:
$.ajax({
url: '/carwash/add',
dataType: 'json',
type: 'PUT',
success: function(data) {
this.setState({});
}.bind(this),
error: function(xhr, status, err) {
console.error('/carwash/add', status, err.toString());
}.bind(this)
})
My application is handeling by spring security which has the following configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/login", "/logout", "/resources/*").permitAll()
.antMatchers("/owner").access("hasRole('ROLE_OWNER')")
.antMatchers("/admin").access("hasRole('ROLE_ADMIN')")
.antMatchers("/carwash").access("hasRole('ROLE_OWNER')")
.and().formLogin().loginPage("/login").successHandler(authenticationSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/login?error");
}
NB: user that call ajax requst has role 'ROLE_OWNER' and can reach "/owner" and "/carwash" without problem.
Also my controller which is resposible for put request:
#RequestMapping(value = "/carwash/add", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.OK)
#ResponseBody
public void addCarWashPOST(){
System.out.println("inside addCarWash");
}
#RequestMapping(value = "/carwash/add", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.OK)
#ResponseBody
public void addCarWashPUT(){
System.out.println("inside addCarWash");
}
All my application is based on spring boot therefore I have also log after this PUT request:
DEBUG 12640 --- [nio-8080-exec-9] o.s.web.servlet.DispatcherServlet : Successfully completed request
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/login]
DEBUG 12640 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /login
DEBUG 12640 --- [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
DEBUG 12640 --- [io-8080-exec-10] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
DEBUG 12640 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
WARN 12640 --- [io-8080-exec-10] o.s.web.servlet.PageNotFound : Request method 'PUT' not supported
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Successfully completed request
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/error]
DEBUG 12640 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
DEBUG 12640 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
DEBUG 12640 --- [io-8080-exec-10] o.s.web.cors.DefaultCorsProcessor : Skip CORS processing: request is from same origin
DEBUG 12640 --- [io-8080-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Wed Sep 14 20:17:20 CEST 2016, status=405, error=Method Not Allowed, exception=org.springframework.web.HttpRequestMethodNotSupportedException, message=Request method 'PUT' not supported, path=/carwash/add}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#78b6776e]
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG 12640 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Successfully completed request
One more interesting issue, if substitute in ajax request type to POST the exeption will be different: /carwash/add parsererror SyntaxError: Unexpected token < in JSON at position 0
The log from spring boot for POST request:
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/login]
DEBUG 13348 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /login
DEBUG 13348 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String biz.controllers.mvc.LoginController.login()]
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/login] is: -1
DEBUG 13348 --- [nio-8080-exec-2] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'login'
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'login'; URL [WEB-INF/pages/login.html]] in DispatcherServlet with name 'dispatcherServlet'
DEBUG 13348 --- [nio-8080-exec-2] o.s.w.servlet.view.InternalResourceView : Forwarding to resource [WEB-INF/pages/login.html] in InternalResourceView 'login'
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/pages/login.html]
DEBUG 13348 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /WEB-INF/pages/login.html
DEBUG 13348 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/WEB-INF/pages/login.html]
DEBUG 13348 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/WEB-INF/pages/login.html] are [/**]
DEBUG 13348 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/WEB-INF/pages/login.html] are {}
DEBUG 13348 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/WEB-INF/pages/login.html] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#1aa2d29f] and 1 interceptor
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/WEB-INF/pages/login.html] is: -1
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
DEBUG 13348 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
and as I undestand from log, the application cannot No matching bean found for view name 'login' how ever I have a controller for #RequestMapping(value ={"/", "/login"}, method = RequestMethod.GET) and without problem can open page with link /login... What I miss ?
Controller for "/" and "/login"
#RequestMapping(value ={"/", "/login"}, method = RequestMethod.GET)
public String login() {
return "login";
}
Configuration:
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("WEB-INF/pages/");
resolver.setSuffix(".html");
return resolver;
}
To make an AJAX/JSON request with CSRF enabled you have to pass CSRF token as a HTTP Request Header, not a parameter or other data.
On the page, your meta tags should look like these:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
Then, prepare values somewhere in the JS code:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
Pass the CSRF token as a header:
$.ajax({
type: "PUT",
async: false,
url: '/carwash/add',
data: [your data],
beforeSend: function(xhr) {
// here it is
xhr.setRequestHeader(header, token);
},
success: function(obj) {
// ....
},
....
You can see more here
http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html

spring boot runs but the pages are not accessible

When I access my app via browser I get an 404 (Whitelabel Error Page).
After searching around, I think it could be a problem with my sitemesh filter.
#Bean
public FilterRegistrationBean sitemesh() throws Exception {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MySiteMeshFilter());
return filterRegistrationBean;
}
MySitemeshFilter:
protected static class MySiteMeshFilter extends ConfigurableSiteMeshFilter {
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath("/*", "/decorators/basic-theme.jsp");
}
}
What do you think? Thank you!
EDIT:
It could be also possible, that my Security Configuration is the problem:
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private MongoTemplate mongoTemplate;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/error").permitAll()
.antMatchers("/register*", "/login", "/lostPassword").anonymous()
.antMatchers("/admin","/admin**").hasRole("ADMIN")
.antMatchers("/user", "/user/**", "/offer/*", "/page", "/page/**").hasAnyRole("USER", "COMPANY_USER", "COMPANY_MASTER", "ADMIN")
.antMatchers("/company", "/company/**").hasAnyRole("COMPANY_USER", "COMPANY_MASTER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").failureUrl("/login?error=true").usernameParameter("username").passwordParameter("password").loginProcessingUrl("/security_check")
.successHandler(new MyAuthenticationSuccessHandler(this.mongoTemplate));
http.logout().logoutUrl("/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new MyUserDetailsService(this.mongoTemplate)).passwordEncoder(new ShaPasswordEncoder(256));
}
}
EDIT 2:
The controllers are not resolved. Setting the #ComponentScan "basePackages" attribute helps. The controller-methods are now being executed. But it looks like spring boot cannot find my views(directory) to render the page.
EDIT 3:
This is a part of my logging output. Is there anything unusual? It starts with INFO log (log4j) "starting page" which I put in the method ("/") of my controller. The controller method belonging to the RequestMapping is fired, but I think spring boot cannot find the jsp.
2014-12-30 10:20:09.422 INFO 5884 --- [nio-8080-exec-3] c.l.c.controller.PublicController : starting page
2014-12-30 10:20:09.426 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8] based on Accept header types and producible media types [*/*])
2014-12-30 10:20:09.427 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'home'
2014-12-30 10:20:09.427 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.web.servlet.view.JstlView: name 'home'; URL [/WEB-INF/views/home.jsp]] based on requested media type 'text/html'
2014-12-30 10:20:09.427 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.JstlView: name 'home'; URL [/WEB-INF/views/home.jsp]] in DispatcherServlet with name 'dispatcherServlet'
2014-12-30 10:20:09.433 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.view.JstlView : Forwarding to resource [/WEB-INF/views/home.jsp] in InternalResourceView 'home'
2014-12-30 10:20:09.435 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/views/home.jsp]
2014-12-30 10:20:09.436 DEBUG 5884 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /WEB-INF/views/home.jsp
2014-12-30 10:20:09.446 DEBUG 5884 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/WEB-INF/views/home.jsp]
2014-12-30 10:20:09.446 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/WEB-INF/views/home.jsp] are [/**]
2014-12-30 10:20:09.446 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/WEB-INF/views/home.jsp] are {}
2014-12-30 10:20:09.447 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/WEB-INF/views/home.jsp] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#727d5eda]]] and 1 interceptor
2014-12-30 10:20:09.448 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/WEB-INF/views/home.jsp] is: -1
2014-12-30 10:20:09.448 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2014-12-30 10:20:09.448 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
2014-12-30 10:20:09.449 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
2014-12-30 10:20:09.450 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2014-12-30 10:20:09.451 DEBUG 5884 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2014-12-30 10:20:09.452 DEBUG 5884 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)]
2014-12-30 10:20:09.452 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2014-12-30 10:20:09.453 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2014-12-30 10:20:09.453 DEBUG 5884 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#5dbc9982] based on requested media type 'text/html'
2014-12-30 10:20:09.453 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#5dbc9982] in DispatcherServlet with name 'dispatcherServlet'
2014-12-30 10:20:09.454 DEBUG 5884 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
2014-12-30 10:20:09.480 DEBUG 5884 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/favicon.ico]
2014-12-30 10:20:09.481 DEBUG 5884 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/favicon.ico] are [/**/favicon.ico]
2014-12-30 10:20:09.481 DEBUG 5884 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/favicon.ico] are {}
2014-12-30 10:20:09.481 DEBUG 5884 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/favicon.ico] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#1742114b]]] and 1 interceptor
2014-12-30 10:20:09.481 DEBUG 5884 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/favicon.ico] is: -1
2014-12-30 10:20:09.490 DEBUG 5884 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2014-12-30 10:20:09.491 DEBUG 5884 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Successfully completed request
In my application.properties I added:
spring.view.prefix=/WEB-INF/views/
spring.view.suffix=.jsp
For any of you who stumbled here looking for an answer to 'o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'home'', Spring has tried and failed to locate a view resolver for 'home'.
If it is pure html you want to serve, you need just return '/home.html' from your controller. Spring will look for this file under /src/main/resources/static and return a response accordingly.
For other ways to resolve views, read this excellent answer, How to map requests to HTML file in Spring MVC?

Resources