spring csrf token from session - spring

Hi I am using Spring MVC 4.3 version. We have using Spring CSRF functionality. springSecurityFilterChain defined in web.xml will make sure to go through CSRFFilter class. As per my knowledge Spring stores csrf token in session.
I have created a controller method which accepts HTTP GET call. This is the first method in my application. First time when I am trying to access the token from session I am getting null. I tried below possibilities only for request.getAttribute("_csrf") call is returning null. Why am I getting null from session call? Is it okay to use request attributes?
HttpSession session = objHttpRequest.getSession(false);
HttpSessionCsrfTokenRepository sessionToken = neWHttpSessionCsrfTokenRepository();
System.out.println("HttpSessionCsrfTokenRepository token = " + sessionToken.loadToken(objHttpRequest)); // Returned **null**
CsrfToken token = (CsrfToken) session.getAttribute("org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN");
System.out.println(">>>>> session token "+ token); // Returned **null**
token = (CsrfToken)objHttpRequest.getAttribute("_csrf");
System.out.println(">>>>> request token "+ token); // Returned token value

Be very careful using session.
The session attribute is set as stated. But it is for the duration of the user interaction. So you don't have any indication on the server side where this came from. So the "bad-guy" code can simply ride on your session and the check will think it is ok.
The token must be part of the form data submitted or as part of the header.

Related

Spring boot: Requests with an expired Cookie is still available after logging out

In the spring boot project, when the user logouts, we invalidate the cookie with this block of code:
//name = "Token"
//value = "expired"
//age = 0
private void setExpiredCookie(HttpServletResponse response, String name, String value, int age) {
Cookie cookie = new Cookie(name, value);
cookie.setSecure(true); //Send cookie to the server only over an encrypted HTTPS connection
cookie.setHttpOnly(true); //Preventing cross-site scripting attacks
cookie.setPath("/"); //Global cookie accessible every where
cookie.setMaxAge(age); //Deleting a cookie. I Passed the same other cookie properties when you used to set it
response.addCookie(cookie);
}
However, after logout, I tested my website with an application for catching the request and resending it through the repeater, with exact values, such as token and payload.
I resent a request, for example, to change the email address, and this request, despite logging out, is valid for 15 minutes (for the life of the original cookie).
What am I missing? Because I am properly deleting and protecting cookies.
You are just creating new cookie.
You should invalidate cookie with session id, which was given to you when you authenticated. Simply use this:
HttpSession session = httpServletRequest.getSession(false);
session.invalidate();

Implement refresh token in Spring Security + Angular

I'm working on this Spring Security implementation with OAuth2 and JWT:
According to the author I can access resources using token this way:
To access a resource use (you'll need a different application which has configured ResourceServer):
http localhost:8080/users 'Authorization: Bearer '$ACCESS_TOKEN
About this step:
To use the refresh token functionality:
http --form POST adminapp:password#localhost:9999/oauth/token grant_type=refresh_token refresh_token=$REFRESH_TOKEN
It's not clear for me when I need to refresh the token and how to handle this part into Angular.
When the Token expires do I need to first send request to the endpoint for refreshing the token and then to the login page?
How this case should be implemented?
At the time of authentication, two JWTs will be created - access token and refresh token. Refresh token will have longer validity. Both the tokens will be written in cookies so that they are sent in every subsequent request.
On every REST API call, the tokens will be retrieved from the HTTP header. If the access token is not expired, check the privileges of the user and allow access accordingly. If the access token is expired but the refresh token is valid, recreate new access token and refresh token with new expiry dates and sent back through Cookies
Access tokens carry the necessary information to access a resource directly. In other words, when a client passes an access token to a server managing a resource, that server can use the information contained in the token to decide whether the client is authorized or not. Access tokens usually have an expiration date and are short-lived.
Refresh tokens carry the information necessary to get a new access token. In other words, whenever an access token is required to access a specific resource, a client may use a refresh token to get a new access token issued by the authentication server. Common use cases include getting new access tokens after old ones have expired, or getting access to a new resource for the first time. Refresh tokens can also expire but are rather long-lived.
High level code
authenticate()
public ResponseEntity<OAuth2AccessToken> authenticate(HttpServletRequest request, HttpServletResponse response, Map<String, String> params) {
try {
String username = params.get("username");
String password = params.get("password");
boolean rememberMe = Boolean.valueOf(params.get("rememberMe"));
OAuth2AccessToken accessToken = authorizationClient.sendPasswordGrant(username, password);
OAuth2Cookies cookies = new OAuth2Cookies();
cookieHelper.createCookies(request, accessToken, rememberMe, cookies);
cookies.addCookiesTo(response);
if (log.isDebugEnabled()) {
log.debug("successfully authenticated user {}", params.get("username"));
}
return ResponseEntity.ok(accessToken);
} catch (HttpClientErrorException ex) {
log.error("failed to get OAuth2 tokens from UAA", ex);
throw new BadCredentialsException("Invalid credentials");
}
}
refreshToken()
Try to refresh the access token using the refresh token provided as a cookie. Note that browsers typically send multiple requests in parallel which means the access token will be expired on multiple threads. We don't want to send multiple requests to UAA though, so we need to cache results for a certain duration and synchronize threads to avoid sending multiple requests in parallel.
public HttpServletRequest refreshToken(HttpServletRequest request, HttpServletResponse response, Cookie refreshCookie) {
//check if non-remember-me session has expired
if (cookieHelper.isSessionExpired(refreshCookie)) {
log.info("session has expired due to inactivity");
logout(request, response); //logout to clear cookies in browser
return stripTokens(request); //don't include cookies downstream
}
OAuth2Cookies cookies = getCachedCookies(refreshCookie.getValue());
synchronized (cookies) {
//check if we have a result from another thread already
if (cookies.getAccessTokenCookie() == null) { //no, we are first!
//send a refresh_token grant to UAA, getting new tokens
String refreshCookieValue = OAuth2CookieHelper.getRefreshTokenValue(refreshCookie);
OAuth2AccessToken accessToken = authorizationClient.sendRefreshGrant(refreshCookieValue);
boolean rememberMe = OAuth2CookieHelper.isRememberMe(refreshCookie);
cookieHelper.createCookies(request, accessToken, rememberMe, cookies);
//add cookies to response to update browser
cookies.addCookiesTo(response);
} else {
log.debug("reusing cached refresh_token grant");
}
//replace cookies in original request with new ones
CookieCollection requestCookies = new CookieCollection(request.getCookies());
requestCookies.add(cookies.getAccessTokenCookie());
requestCookies.add(cookies.getRefreshTokenCookie());
return new CookiesHttpServletRequestWrapper(request, requestCookies.toArray());
}
}

Is there spring boot jwt logout solution in using Cookie storage?

I stored jwt token in Cookie Storage .
I want to remove or expire this token in logout action . how should I do ? Can somebody give me advice?Thank you. I use this following code :
final String token=jwtTokenUtil.generateToken(userDetials);
Cookie cookie = new Cookie("token",token);
cookie.setHttpOnly(true);`enter code here`
response.addCookie(cookie);
based on Delete cookie from a servlet response
Create a new cookie with a value of null and add it to the response. So you would replace
Cookie cookie = new Cookie("token",token);
with
Cookie cookie = new Cookie("token",null);

How to get session token after successful authentication?

After successful authentication via a form post sign-in, I need to be able to use the same session token within the response to do another post to a protected route, but this time using XMLHttpRequest.
How would I get the session token, considering that the successful authentication response has already passed.
The session token is stored in a laravel_session cookie, assuming default Laravel settings (see config/session.php).
You can read the cookie in javascript using document.cookie. For example:
function readCookie(name)
{
var matches = document.cookie.match('(^|; )'+name+'=([^;]*)');
if (matches) {
return decodeURIComponent(matches[2]);
}
return null;
}
var token = readCookie('laravel_session');

jetty with spring MVC session.isNew() returns always false

I am running Jetty 9.3 with Spring MVC and Spring Security. My main page is intercepted by Spring Security Login page which is in JSP. The problem is with my SessionTimeoutIntercepter which should redirect in case of session timeout. What I want to do when the session is timed out - redirect to Spring Security Login page with some parameter like "Session expired". The problem is that session.isNew() which I use always returns false((( I tried with mapping to *"/**"* - the same result. Even after my first request to server and login page - this function returns false((( Can somebody help me why?
I think, that some people may do something like
Session session = request.getSession();
if(session.isNew()) {
//doSmth
}
but method getSession() return new session if it not exists yet. You need getSession(false) - it don't create new session, just return null if it doesn't exists or return old session with timeout expired.
In your case, you can add some logic to interceptor
Session session = request.getSession(false);
if(session == null || session.isNew() {
// do redirect
}

Resources