Passing cookies from jax-rx rest api end point to ejb - ejb

I am looking for a solution related to passing cookies values from JAX-RX REST API endpoint to ejb layer.
I tried searching the solution and found some of them are using thread local. but and thread local supposed to be not working with executor services.
Is there any another solution that I can use to pass cookies values from web/rest later to ejb layer.
Note: I do not want to pass it as method parameter from rest layer to down the ejb layer. I would like to access the cookies values directly in ejb layer
Thanks

Lets say you have a class MyEJB, you can inject HttpServletRequest object to you ejb as follows:
public class MyEJB{
#Context
private HttpServletRequest httpRequest;
}
Now from this request object you can access your required cookies. As follows:
String rawCookie = request.getHeader("Cookie");
String[] rawCookieParams = rawCookie.split(";");
for(String rawCookieNameAndValue :rawCookieParams)
{
String[] rawCookieNameAndValuePair = rawCookieNameAndValue.split("=");
}

Related

Spring MVC - Can I autowire HttpServletRequest in RestController

Can I autowire HttpServletRequest in my RestController like following and will it returns different servletRequest even if it is executed in highly concurrent environment. I have a restriction that I can not have as method parameter because I am implementing an interface which is auto generated and will not have HttpServletRequest as the method parameter.
#RestController
public class MyController implements MyInterface {
#Autowired
private HttpServletRequest servletRequest;
#Override
#RequestMapping(value = "/test", produces = {"application/json"}, consumes = {"application/json"}, method = RequestMethod.POST)
public ResponseEntity<MyResponse> test(#RequestBody final MyRequest payload){
...
}
...
}
I have gone through these SO questions and some other articles on this. But just wanted to ensure that when we autowire HttpServletRequest in the controller then its Scope is Request?
Spring 3 MVC accessing HttpRequest from controller
How are Threads allocated to handle Servlet request?
Scope of a Spring-Controller and its instance-variables
How do I get a HttpServletRequest in my spring beans?
How To Get HTTP Request Header In Java
Note: I did try this and it seems to work fine. But just wanted to confirm that it's a foolproof solution even in a highly concurrent environment.
Also if this is the correct way to do it, I would appreciate if someone can explain how exactly it works.
I have used this and it works fine. But unfortunately I did not find any official documentation which mentions that this should work.
Here is the explanation based on my understanding from debugging the code with running multiple requests with different headers/payload etc.:
Whether we autowire on field or through the constructor, servletRequest acts like a Proxy object which delegates the call to Current HttpServletRequest which is different for each request. Thus, even though it's injected through constructor in a Singleton RestController, it will still have the call delegated to corresponding HttpServletRequest for each new request. This utilizes AutowireUtils.ObjectFactoryDelegatingInvocationHandler to access the current HttpServletRequest object. The java doc for it also says Reflective InvocationHandler for lazy access to the current target object.
Thus even if the autowired Proxy object is always the same for all requests, the underlying target object to which the call is delegated is the current HttpServletRequest object which is per-request.
There is another way you can get HttpServletRequest is using RequestContextHolder as mentioned in this answer
HttpServletRequest currentRequest =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Note: As this explanation is based on my understanding, please do share any official documentation about this if anyone has it.

How to access "session" scoped beans in a Spring WebSocket handler (not "websocket" scope)

In a raw Spring WebSocket application (not using sockjs/STOMP or any other middleware), how can I have Spring inject beans that have been registered in the HTTP session scope so that they can be used by code in my WebSocketHandler bean?
Note that what I am not asking is any of these questions:
How do I create beans in a scope that is accessible to all handler invocations for the same WebSocket session (e.g. as described in the answer to Request or Session scope in Spring Websocket). The beans I need to access already exist in the scope for the HTTP session
How do I (programatically) access objects in the servlet container's HTTP session storage (I haven't tried to do this, but I'm pretty sure the answer involves using an HttpSessionHandshakeInterceptor), but that doesn't get me injection of Spring scoped dependencies.
How to use a ScopedProxy to pass beans between code in different scopes (e.g. as described here); I'm already familiar with how to do this, but attempting to do so for a WebSocketHandler causes an error because the session scope hasn't been bound to the thread at the point the object is accessed.
How to access the current security principal -- again, very useful, but not what I'm currently trying to achieve.
What I'm hoping to do is provide a simple framework that allows for the traditional HTTP-request initiated parts of an MVC application to communicate directly with a WebSocket protocol (for sending simple push updates to the client). What I want to be able to do is push data into a session scoped object from the MVC controller and pull it out in the websocket handler. I would like the simplest possible API for this from the MVC controller's perspective, which if it is possible to just use a session-scoped bean for this would be ideal. If you have any other ideas about very simple ways of sharing this data, I'd also like to hear those in case this approach isn't possible.
You can also use Java API for websocket. This link https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support
explains how to do this with Spring.
Ufortunately, something like this
#ServerEndpoint(value = "/sample", configurator = SpringConfigurator.class)
public class SampleEndpoint {
private SessionScopedBean sessionScopedBean;
#Autowired
public SampleEndpoint(SessionScopedBean sessionScopedBean) {
this.sessionScopedBean = sessionScopedBean;
}
}
causes exception (because we're trying to access bean outside its scope), but for singleton and prototype beans it works well.
To work with session attributes you can modify the hanshake and pass required attributes:
public class CustomWebSocketConfigurator extends SpringConfigurator {
#Override
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request,
HandshakeResponse response) {
//put attributes from http session to websocket session
HttpSession httpSession = (HttpSession) request.getHttpSession();
config.getUserProperties().put("some_attribute",
httpSession.getAttribute("some_attribute_in_http_session"));
}
}
P. S. More a comment than an answer. I just wanted to add another way of handling session attributes in websocket to your question-answer. I have been searching the web for exactly the same issue and the way showed above seems to me the most systematic approach to handling the session data in websocket.

Is there a way to access HTTP headers in a Java EE interceptor?

I have a JSP page that invokes an EJB method and I am using a Java EE interceptor for the EJB method. So the method checkHeaders of the interceptor will be executed before the EJB method
My question is: How can I access the HTTP headers in the interceptor method?
My application is running in JBOSS 6.1
// interceptor class
#AroundInvoke
public Object checkHeaders(InvocationContext invocationContext)
throws Exception {
// I need something here to access the HTTP headers:
invocationContext.getHTTPHeaders();
.....
//do something with the headers
//continue execution
invocationContext.proceed();
Thanks!
There is not way to access some HTTP request specific attributes in service layer (i.e. in EJB) until you explicitly pass them to EJB method. So if you really need it, you can add extra parameter to your EJB method, like List<String> headers or Map<String, String> headers and read parameter value in your interceptor:
public Object checkHeaders(InvocationContext context) throws
Exception{
if (ctx.getMethod().getName().equals("yourTargetMethod")) {
// assume your 'headers' parameter is first method param
List<String> headers = (List<String>) ctx.getParameters()[0]);
}
}
You can't access the HTTP headers from and EJB Interceptor because the EJB container is independent of the web tier. You would either pass the headers into your EJB method call and check them as part of its business logic or perform the check in the JSP/web tier. I would go with the latter since you won't be leaking web concerns / dependencies into your business/EJB tier.

What is the correct approach for denying access to specific resources in spring MVC + security

I've seen many questions requesting how to handle security scenarios, all either have solutions for method annotations (i.e. #PreAuthorize("hasRole('ROLE_USER')")) or using a point-cut.
However what if the resource isn't known if the user has access until the resource has been read from a data store? Let's consider a user who has access to a set of customers, the rest endpoint for these customers can be found at /customers/{id}. A user is only allowed access if they have been granted access to read the account, likewise they must also have access to make a POST to the same endpoint.
One way would be:
#RequestMapping(value = "/customers/{id}", method = RequestMethod.GET)
public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) {
if (!req.isUserInRole("ROLE_ADMIN") && !cs.accessGranted(id, principal.getName())) {
throw new AccessDeniedException("You do not have access to view this custoemr.");
}
Customer cust = cs.getCustomer(id);
if (cust == null) {
throw new ResourceNotFoundException("Customer does not exist!");
}
ModelAndView mov = new ModelAndView("customers/info");
mov.addObject("customer", cust);
return mov;
}
I'm wondering if this is the right approach though.
UPDATE: Call to accessGranted was meant to have id as an argument which I missed.
There is a way to continue use #PreAuthorize annotations. You can call beans directly from SpEL expression:
#PreAuthorize("hasRole('ROLE_USER') and !#cs.accessGranted(#principal.getName())")
public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) {
#cs refers to bean id = "cs" declared somwhere in your application context. Later you can future simplify it by removing Principal principal method parameter and getting username directly in SpEL.
If your find yourself using this tehnique often then check out Spring Security ACL module.
My favorite way is to use the #Secured annotation on a method, which takes an array of Strings representing the Role(s) required to execute the method. I like this method because you are not limited to putting security only on URL patterns. For instance, you can add this to a method in your Service class, and any Controller using that Service is now secured.
The other common method is to include URL filters in the Spring Security XML file. I forget the exact syntax, but you basically setup filters that match a URL and indicate what Role(s) are needed.

Using ASP.NET Response and Request objects in a web client class

I currently have a webclient class that maintains session for my web application using session variables but I want to instead use cookies to maintain session. I of course don't have access to the ASP.NET Response and Request variables in this class. Would I have to pass those objects to the webclient class?
Not sure what are you trying to achieve, but in any of your custom classes inside of ASP.NET application you can access Request and Response via
HttpContext.Current.Request
and
HttpContext.Current.Response
As Yuriy pointed out you could access the request/response objects directly via the HttpContext.Current namespace, this however is bad practice. Your class has a dependency on the request/response objects, these should be passed into your class via it's constructor.
e.g.
public class SessionExample{
public SessionExample(System.Web.HttpRequest request, System.Web.HttpResponse response){
}
}
Or if your class is meant to live for longer than the duration of a single http request you can pass them in as method paramaters
public class SessionExample{
public SessionExample(){
}
public void DoSomething(System.Web.HttpRequest request, System.Web.HttpResponse response){
}
}
Structuring your code this way makes it more testable and will save you headaches down the road.

Resources