Setting Response to session - java

Setting response in session
#ResourceMapping("SomeValue")
public void getSites(ResourceRequest request, ResourceResponse response) {
try {
String _emailAddress = UserUtils.getEmailAddress(request);
//Service call here
// Need not call the service if the user is in session.
render(sitesXML, MediaType.TEXT_XML.toString(),response);
}catch{
...}
...
...
return MYVALUE;

What framework are you using??
If you are using a framework, surely you can have a reference of the session object within the getSites() method. Try getting a session object from your framework.
Your code may look like as below,
String sitesXML="";
if(sessionObject.get("sitesXmlKey") == null){
sitesXML = (String) sitesService.getSitesForUser(String.class,_emailAddress);
sessionObject.put("sitesXMLKey",sitesXML);
}else{
sitesXML = (String)sessionObject.get("sitesXmlKey");
}

Related

How to access the logged in principal from HttpSessionListener with Java EE Security?

I have an application with #CustomFormAuthenticationMechanismDefinition, and I would like to log the username, session id, IP address, etc. both at login and at logout. The HttpAuthMechanism that gets applied with this annotation associate the given session with the principal, which I can access through the SecurityContext. With a direct logout, I have no problem logging, but I would also like to log when session times out. So I created a HttpSessionListener and in its sessionDestroyed() method I try to access the logged in user through SecurityContext, but it returns an empty set, maybe because the securityContext got invalidated already.
One solution I have in my mind is to store the user principal in a session parameter (which likely happens with the HttpAuthMechanism implementation) and access it from there from the HttpSessionEvent object, but that doesn't feel like the cleanest solution. Is there another Listener I can use or some other solution?
I went with the custom HttpAuthenticationMechanism, here is it if anyone would need it (though I would be more than glad to have some feedback on whether or not it has any security flaws, or improvements).
In an #ApplicationScoped class implementing HttpAuthenticationMechanism:
#Override
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException {
if (!httpMessageContext.isProtected()) {
return httpMessageContext.doNothing();
}
HttpSession session = request.getSession(false);
Credential credential = httpMessageContext.getAuthParameters().getCredential();
// If we already have a session, we get the user from it, unless it's a new login
if (session != null && !(credential instanceof UsernamePasswordCredential)) {
User user = (User) session.getAttribute("user");
if (user != null) {
return httpMessageContext.notifyContainerAboutLogin(user, user.getRoles());
}
}
// If we either don't have a session or it has no user attribute, we redirect/forward to login page
if (!(credential instanceof UsernamePasswordCredential)) {
return redirect(request, response, httpMessageContext);
}
// Here we have a Credential, so we validate it with the registered IdentityStoreHandler (injected as idStoreHandler)
CredentialValidationResult validate = idStoreHandler.validate(credential);
Context context = new Context();
context.setIp(request.getRemoteAddr());
if (validate.getStatus() == CredentialValidationResult.Status.VALID) {
session = request.getSession(true);
CallerPrincipal callerPrincipal = validate.getCallerPrincipal();
session.setAttribute("user", callerPrincipal);
context.setUser(callerPrincipal);
context.setSessionId(session.getId());
Logger log = new Logger(logger, "validateRequest", context);
log.debug("Logged in user: " + callerPrincipal.getName());
String redirectPage = "whatYouWant.xhtml";
redirect(request, response, httpMessageContext, redirectPage);
return httpMessageContext.notifyContainerAboutLogin(validate);
} else if (validate.getStatus() == CredentialValidationResult.Status.NOT_VALIDATED) {
return redirect(request, response, httpMessageContext);
} else {
// Logging
return httpMessageContext.responseUnauthorized();
}
}
And in an implemented HttpSessionListener:
#Override
public void sessionDestroyed(HttpSessionEvent se) {
User user = (User) se.getSession().getAttribute("user");
if (user != null) {
// logging
}
}

java - get cookie value by name in spring mvc

I'm working on a java spring mvc application. I have set a cookie in one of my controller's methods in this way:
#RequestMapping(value = {"/news"}, method = RequestMethod.GET)
public ModelAndView news(Locale locale, Model model, HttpServletResponse response, HttpServletRequest request) throws Exception {
...
response.setHeader("Set-Cookie", "test=value; Path=/");
...
modelAndView.setViewName("path/to/my/view");
return modelAndView;
}
This is working fine and I can see a cookie with name test and value "value" in my browser console. Now I want to get the cookie value by name in other method. How can I get value of test cookie?
The simplest way is using it in a controller with the #CookieValue annotation:
#RequestMapping("/hello")
public String hello(#CookieValue("foo") String fooCookie) {
// ...
}
Otherwise, you can get it from the servlet request using Spring org.springframework.web.util.WebUtils
WebUtils.getCookie(HttpServletRequest request, String cookieName)
By the way, the code pasted into the question could be refined a bit. Instead of using #setHeader(), this is much more elegant:
response.addCookie(new Cookie("test", "value"));
You can also use org.springframework.web.util.WebUtils.getCookie(HttpServletRequest, String).
private String getCookieValue(HttpServletRequest req, String cookieName) {
return Arrays.stream(req.getCookies())
.filter(c -> c.getName().equals(cookieName))
.findFirst()
.map(Cookie::getValue)
.orElse(null);
}
Spring MVC already gives you the HttpServletRequest object, it has a getCookies() method that returns Cookie[] so you can iterate on that.
private String extractCookie(HttpServletRequest req) {
for (Cookie c : req.getCookies()) {
if (c.getName().equals("myCookie"))
return c.getValue();
}
return null;
}
Cookie doesnt have method to get by value try this
Cookie cookie[]=request.getCookies();
Cookie cook;
String uname="",pass="";
if (cookie != null) {
for (int i = 0; i < cookie.length; i++) {
cook = cookie[i];
if(cook.getName().equalsIgnoreCase("loginPayrollUserName"))
uname=cook.getValue();
if(cook.getName().equalsIgnoreCase("loginPayrollPassword"))
pass=cook.getValue();
}
}

Wicket tests: mock attribute to HttpSession

guys.
I have the following code for my http session at Wicket-based application:
public static HttpServletRequest getHttpServletRequest() {
Request request = RequestCycle.get().getRequest();
if (request != null && request instanceof WebRequest) return
HttpServletRequest) request.getContainerRequest();
return null;
}
public static SessionObject getSessionObject() {
HttpServletRequest request = getHttpServletRequest();
HttpSession session = request == null ? null : request.getSession();
SessionObject so = session == null ? null : (SessionObject) session.getAttribute("so");
if (so == null) {
logger.warn("SessionObject is not found in HttpSession!");
}
return so;
}
The session object is initialized at jsp like the following:
jsp:useBean id="so" class="package.SessionObject" scope="session"
I'd like to mock this attribute so into Wicket tests.
Tried to do the following:
bind(SessionObject.class).toInstance(EasyMock.createMock(SessionObject.class));
also
tester = new WicketTester(new MockApplication() {
#Override
public Session newSession(Request request, Response response) {
final Session session = super.newSession(request, response);
session.setAttribute("so", EasyMock.createMock(SessionObject.class));
return session;
}
});
But when I try to call method as:
init(){
a = getSessionObject().getA();
}
getSessionObject() returns null because there are no attribute named "so".
Could you help please me to mock this attribute into session?
You can simplify your helper methods to: Session.get().getAttribute("so").
Your code that writes the value already uses Session#setAttribute().
Try by binding the session: Session#bind(). Unless bound Wicket will create a new instance of Session for each request. Once bound Wicket will acquire HttpSession and store Wicket's Session into it (as attribute).
If this doesn't help then put a breakpoint at Session set/getAttribute() methods and see what happens.

How to add a cookie using doTag method in custom tag?

I have developed a custom tag library in Java which I use in my web application.
I am not sure why but my doTag() is not setting up cookie at all. I have cleared my cache and restarted my computer as well. Here is the code:
public class UserVersionOfSite extends EvenSimplerTagSupport {
private static final Log logger = LogFactory.getLog(UserVersionOfSite.class);
private StringWriter sw = new StringWriter();
#Override
public void doTag() throws IOException, JspException {
getJspBody().invoke(sw); //get the tag body and put it in StringWriter object
//get request object to get cookie value
PageContext ctx = (PageContext)getJspContext();
HttpServletRequest httpServletRequest = (HttpServletRequest) ctx.getRequest();
HttpServletResponse httpServletResponse = (HttpServletResponse) ctx.getResponse();
if(httpServletRequest.getParameterMap().containsKey("show_full_site")) {
logger.debug("show_full_site ");
if(!checkIfCookieExists(httpServletRequest)){
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
httpServletResponse.addCookie(cookie);
//write the tag output
if(!httpServletRequest.getParameter("show_full_site").equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}else{
String cookieValueString = getCookieValue(httpServletRequest.getCookies(),"SHOW_FULL_SITE","false");
if(!cookieValueString.equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}
}
}
#Override
public String getResult() throws IOException {
return "User version of site";
}
public String getCookieValue(Cookie[] cookies,
String cookieName,
String defaultValue) {
for(int i=0; i<cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName()))
return(cookie.getValue());
}
return(defaultValue);
}
public boolean checkIfCookieExists(HttpServletRequest httpServletRequest){
logger.debug("inside checkIfCookieExists()");
boolean cookiePresent = Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
return cookiePresent;
}
}
Even I tried adding the code without using if else statements but still no success. Is there any thing critical I am missing?
Any ideas guys??!!! I have checked the browser's setting as well, but there is nothing there which is blocking a creation of cookie!
I realise the horse has probably bolted by the time I'm posting this but, for the benefit of others stumbling across it, I think the problem may be related to the feature of RequestDispatcher highlighted in this question: unable to add a cookie included in JSP via jsp:include
your following line inside checkIfCookieExists() method is wrong:
Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
HttpServletRequest.getCookies() returns Cookie[]. You are wrapping it inside a List and checking for a string "SHOW_FULL_SITE" inside this.
Coming back to your question- how do you know cookie is not being set in the HTTP headers? Try using browser plugins like firebug to see the HTTP response headers coming from server. Also set the path of cookie before adding it to response e.g.
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
cookie.setPath("/");

Avoid double authentication when using custom bean spring security

I have a login form that calls a certain LoginBean, which returns a ajax callback parameter indicating whether the credentials are valid or not.
The code is as follows:
public void doLogin() {
Authentication authenticationRequestToken =
new UsernamePasswordAuthenticationToken(user, password);
try {
Authentication authenticationResponseToken =
authenticationManager.authenticate(authenticationRequestToken);
SecurityContextHolder.getContext().
setAuthentication(authenticationResponseToken);
if (authenticationResponseToken.isAuthenticated()) {
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg;
boolean loggedIn = true;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", user);
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
}
} .authenticate(...) catches ...
// Here I need some code that continue whatever j_spring_security_check
// would do after authenticating.
}
The way my application is working now, after this call to doLogin(), the form is submited to j_spring_security_check, and then the authentication process takes place again, wasting previous work.
I'm trying to find a solution for this, any help is appreciated.
So, the bottom line is that I need something that would simulate what happens when j_spring_security_check is intercepted by the filters (or a way to force this interception explicitly), so the processing would take place behind the button, not after the form is submited.
It will be better if you just forward to the spring security authentication url instead of using the SecurityContextHolder yourself. Look at this code:
public String doLogin() throws ServletException, IOException {
FacesContext context = FacesContext.getCurrentInstance();
String springCheckUrl = this.buildSpringSecurityCheckUrl();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
RequestDispatcher dispatcher = request
.getRequestDispatcher(springCheckUrl);
dispatcher.forward((ServletRequest) request,
(ServletResponse) context.getExternalContext.getResponse());
context.responseComplete();
return null;
}
private String buildSpringSecurityCheckUrl() {
StringBuilder springCheckUrl = new StringBuilder(
"/j_spring_security_check").append("?").append("j_username")
.append("=").append(this.userName.trim()).append("&")
.append("j_password").append("=")
.append(this.userPassword.trim());
return springCheckUrl.toString();
}
}

Categories

Resources