Popular Posts

Thursday, March 3, 2016

Disabling Default Spring File Extension Response Mapper


The other day I was trying to implement a file download functionality, which takes the filename as a path variable and returns you the uploaded file metadata. In my case file extension was not matching the response type and Spring was throwing this exception below:

 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation  

The problem was that Spring treats the part after the dot in the url as a file extension and was trying to determine the matching response type and didn't find any matching converter, which result in throwing the above exception.

To solve we can simply disabled the default suffix-based content negotiation and can use the produce annotation to tell Spring what response type should be used.

Code:

1:  @Configuration  
2:  public class ContentNegotiationConfig extends WebMvcConfigurerAdapter {  
3:    @Override  
4:    public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {  
5:      // Turn off suffix-based content negotiation  
6:      configurer.favorPathExtension(false);  
7:    }  
8:  }  

Note: It is important to use the configuration annotation so this property can be set before starting the spring container.

Saturday, February 6, 2016

Unauthorized Entry Point with Spring Security


Let's say you already have secured your app with spring security but now every time a request comes in and you are not able to authenticate the user and the web server returns a 403 Forbidden exception instead of 401 Unauthorized exception, weird right! Well that's the default behaviour which is not correct logically because:

HTTP 401 Unauthorized Exception is for authentication, means the user is not authenticated by the app, the app doesn't know who the user is, it might be because of bad/missing credentials or wrong username or whatever else but in short the user is not authenticated, so please try again.

HTTP 403 Forbidden Exception is for the protected resource, means the user is authenticated user but he doesn't have the right privileges to access the resource so either ask your administrator to give you the privileges or forget about it simple.

Summarizing above, a 401 Unauthorized response should be used for missing or bad authentication, and a 403 Forbidden response should be used after authenticating the user, so the user is authenticated but isn’t authorized to perform the requested operation on a given resource.

Code:

1:  public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {  
2:    
3:    @Override  
4:    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {  
5:    
6:      //log statement if you want to log it to server logs.  
7:      response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User Authentication cannot be verified, Please log in again with your credentials");  
8:    
9:    }  
10:  }  

Now you need to register this entry point in your spring security web configurer class, like this :

1:  http.exceptionHandling().authenticationEntryPoint(new UnauthorizedEntryPoint());  

Please comment, if you have any questions or concerns.

Monday, January 18, 2016

Rendering View in JavaServer Faces (JSF)


Those who works with JavaServer Faces will agree with me that it's quite a difficult job to clear out the current view if the current view is stuck in validation phase. I came across a scenario in which I need to display errors to client and move forward only with his request if the client has fixed all errors, normal flow, right? But what if the client wants to cancel the first step and wants to forward to the next step without fixing errors. So then in this scenario instead of clearing the errors one by one JSF allows you to create a whole new view by replacing the current view and allows the request to proceed further.

If you need to clear the current view, take a look at this clear function below:

1:   public void createCurrentView()   
2:   {  
3:     FacesContext context = FacesContext.getCurrentInstance();  
4:     Application application = context.getApplication();  
5:     ViewHandler viewHandler = application.getViewHandler();  
6:     UIViewRoot viewRoot =   
7:            viewHandler.createView(context, context.getViewRoot().getViewId());

8:     context.setViewRoot(viewRoot);  
9:     context.renderResponse();  
10:   }  

The above function will try to get the current view from the context, creates a new view and replace the current with the new one in the context.

You should only clear the whole current view in rare cases as creating view again and again might impact your performance and it is also not recommended by industry experts to use it for frequent web flows.

Please share, How it goes!