Spring MVC, how to have a controller handler handle all the requests before the mapped handlers? - spring

I've wrote a web app with its brave controllers and handler mapping, everything with Spring 3.0 and controller annotations. Now turns out that I need simple and custom autentication. I don't want to use ACEGI for the moment, because I've no time to learn it. I'd like ideally that I could have a routine that gets called before every mapped handler, gets from the HttpSession the userId, checks if he is logged in and the session key and if not redirects to a login page. I've been thinking about an interceptor... the problem is that you have to use HandlerInterceptorAdapter, which has the following method:
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
that won't let me access the HttpSession associated with the request. How do I solve this?

Are you sure? You should be able to obtain the session through request.getSession().

Related

HttpServletRequest throws error when used within Aspect

I have a method which has an aspect. When I try to #Autowire HttpServletRequest, and use request.getHeader(something), I get this error -
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
How do I fix this? I tried using RequestContextHolder, but upon debugging I still see null. How do I use the RequestContextListener when my project has no web.xml.
Request Header can be accessed using HttpServletRequest below way.
private static HttpServletRequest getRequest() {
return((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getApiTraceId() {
return getRequest().getHeader(something);
}
Aspect annotations spins a new thread which is different from the one httpservlet is available in. This is why request was not available within the #ASpect. To resolve it, call the request object BEFORE the aspect method, cache it and call the same method as before.

Save the Spring Security Context back to session for subsequent use

My SpringBoot application is a packaged software application, to customize it I want to manipulate the authentication object when users first login, and I expect this object would be pushed back to the user's session for subsequent connection.
I managed to use an Around advice to intercept a REST endpoint that will be triggered when first login:
#Around("execution( * com.myproject.CurrentUser.get(..)))"
public ResponseEntity getCurrentUser(ProceedingJoinPoint pjp) throws Exception {
SecurityContextHolder.getContext().setAuthentication(getNewAuthentication());
((ServletRequestAttributes) RequestContextController.currentRequestAttributes())
.getRequest().getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING.SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
ResponseEntity response = (ResponseEntity) pjp.proceed();
return response;
}
The getNewAuthentication() method is confirmed OK, it returns a PreAuthenticatedAuthenticationToken that includes additional authorities.
However in the subsequent REST calls when I check the Security Context object the authentication is still the original one.
May I know what would be the proper way to do this? I need to manipulate the authentication object at the very beginning and make sure the subsequent calls will make use of it.
Any idea?

HttpServletRequest Object in Simple java file

I am working on the Web Project, and i want to get the information of the request object in our simple java program which is not extending the HttpServlet class.
The same problem i am facing in the #init() of servlet , i want to call some functions in init() in that i need request object , but i am not getting how can i do this functionality.
please do not post any answer with related to the Spring technology :)
I googles alot but didn't find anything for this.Please help me out.
First of all, HttpServletRequest and HttpServletResponse are interfaces.
The implementation classes for these interfaces are provided
by the application server (server container) vendor (like Tomcat, JBoss, Glassfish,
etc..).
When the application server (where the your web application is
deployed), receives the request from the client, the objects for the
HttpServletRequest and HttpServletResponse implementation classes are
created. And the creation of these objects happens for each hit
(request) from client.
In general, these request/response objects (created by container) will be passed to the HttpServlet class as method parameters, from which we will retrieve the data the client intended to send to the server/servlet methods inside doGet() or doPost() (using request.getParameters() method).
Also refer below docs to know more about the HttpServletRequest and HttpServletResponse are interfaces.
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

Access Denied Spring Security with javaconfig

I hope you could give me a hand with the following:
I am using spring security and spring MVC to build a web app, and I need to redirect the flow to the login page, once there is a try to access a forbidden resource (403 HTTP status code).
Now, spring Security already does the work of preventing from unauthorized access to every resource I've exposed in my Restful API (#RestController), and responding with the proper 403 default page. But as I need to redirect to the login page, I need to push spring security to do a redirect instead of sending a 403. In this regard I've been trying to do the following but I haven't been able to make it works:
Setting the HttpSecurity bean to manage the exception when accessing a denied page:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().exceptionHandling().accessDeniedPage("/security/403");
}
Now, I set my controller to catch /security/403 URL
// for 403 access denied page
#RequestMapping(value = "/security/403", method = RequestMethod.GET)
public void accesssDenied() {
//Do stuff here, redirecting or whatever.
}
thanks
Create a new class that acts as an Interceptor.
This class will implement the HandlerInterceptor interface and override the following methods:
From the documentation:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) – Intercept the execution of a handler (called just before the controller).
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) – called immediately after the controller
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler) – called just before sending response to view
In your case, use the preHandle() method to check if the client is trying to access a forbidden resource and if so, redirect the client to the login page. In fact, this is one of the most common paradigms where an Interceptor is used to handle the flow of execution.

Creating a session cookie inside a controller

I'm new to Tomcat, servlets and Spring Web. I'm coming from a PHP background so I'm a little disoriented to say the least. I want a controller to create a session cookie for me.
I've been told that I can get the session like this in a standard servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Somewhere inside the method...
HttpSession session = request.getSession(true);
// Set a cookie
session.setAttribute("hello", "world");
// More stuff...
}
How does this translate into the Spring Web MVC way of doing things? Can I create session cookies inside a controller?
What you are doing in your example have nothing to do with cookies.
session.setAttribute("key", valueObject);
Sets a java-object in the session. The session is kept at the server. The sessionid is the only thing communicated back to the client. It can be a cookie or it can be in the URL. The attributes in the session is not serialized to strings.
Cookies on the other hand are strings that are sent back to the client. It is the clients responsibility to store their cookies (and some people turn them off) and return them to the server.
Setting a cookie value from a complex object-graph will require serialization and deserialization. A session attribute will not.
If you want to read a cookie, use this:
#CookieValue("key") String cookie
In the controller parameter list. The cookie variable will be populated with the value from the cookie named "key".
To set a cookie, call:
response.addCookie(cookie);
In Java Servlets (and Spring MVC in particular) you don't interact with session cookie directly, actually properly written servlet based application should work without cookies enabled, automatically falling back to URL based session id.
The way you provided is correct, although Spring is giving you much better (higher level) approaches like session-scoped beans. This way you never interact with the session itself.
You can get access to the HttpSession object by including it as a parameter in your controller's method(s):
public String get(Long id, HttpSession session) {
}
Spring will inject the current HttpSession object for you, and from there you can set attributes (like you did in your question).

Resources