Missing CSRF token in REST request - spring

I'm writing a REST API using Spring MVC. I'm trying to access a controller method via a POST request.
I always receive a 403error:
Invalid CSRF Token '' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
How can I deliver a CSRF token within my REST request?
I tried to use the default security password which is displayed during application startup as the value for _csrf but it wasn't successful.
How can I retrieve the CSRF token and is it correct to send the token in the _csrf parameter?

You will need to provide the correct header and CSRF token when making the request e.g.
request.setRequestHeader('${_csrf.headerName}', '${_csrf.token}');
You can also send the token as a request parameter using _csrf.parameterName.

Related

Spring Security - CSRF token on GET request

I configured CSRF protection in my Spring 5 (Boot 2) RESTful web service because I want to prevent CSRF attacks (I am using JWT cookie for authentication and authorization). On each request I am getting a new XSRF cookie. The value of that cookie I am sending back through the X-CSRF-TOKEN header.
I noticed that POST, PUT and DELETE methods require the value of this token (in the X-CSRF-TOKEN header) in order to work properly, but GET method works just fine without X-CSRF-TOKEN header.
Is this behavior intentional because GET method should not change state or I did something wrong?
CSRF token is intentionally excluded from GET to avoid token leakage to a 3rd party

send api_token through header instead of query parameter

I am trying to build APIS in laravel 5.6, and for api authentication I am using laravel basic API token authentication.
For get request or post request, I need to pass api_token in the query parameter. Is there any way where I can pass the api_token in the header instead of url string?
I followed Laravel - Send api_token within the header .
For GET endpoint, my api url is like this
http://localhost:8000/api/category-list?api_token=YDYsOgkSIOWDdE1NG3Ih1yCkciatOPvtpF1gXTmy8GL1r72mcDEgNDkkZ5jh&Accept=application%2Fjson
For POST my parameter are like this
As you can see, for get I need to add the api token in the url, and for POST I need to add in the body.
If I add the api token in the header, it says unauthorized access.
Header setting where authorization does not work
When you send api token through header the name of the header should be Authorization not api_token.
Also prepend the type of token Bearer to authorization header.
So finally the header should look like:
Authorization: Bearer aEzKClugYHJQsr6If48i1y24KneTT7YwMtNrri7JNhGyEIbJv6YP5SrsFXx2

Spring Security: How to pass oauth2 access token in request headers

On successful login to my spring security application configured with Oauth2, I received a response with Oauth2 token.
For the subsequent request I passed Oauth2 access_token in URI Query Parameter like this
http://localhost:8090/myapplication/users/user?access_token=4c520795-eb07-4c2d-a91b-474c85fb481e
It is working fine.
But instead of passing token in URI to make it more secure I wanted to send token in request headers.How to do this?
Use the usual HTTP Authorization header:
Authorization: Bearer <your-token-here>
For example
Authorization: Bearer 4c520795-eb07-4c2d-a91b-474c85fb481e

Spring Security - securing REST API

I am using Spring Security to secure a REST API.
I use a custom filter which checks if requests contain a valid JWT Token in the header. If the request contains a valid token, an authentication object is added to the security context, otherwise i add null to the security context.
I have also defined an AuthenticationEntryPoint which simply returns 401 when there is an Authentication Exception.
In my security xml, i define a series of intercept-urls. Some of them have access set to "isAuthenticated()" and some have access set to "permitAll".
When i make a request to a URL that has access set to "isAuthenticated()" with a valid JWT token in the header, that works fine. However, when i make a request with no token to a URL with access set to 'permitAll', an exception is thrown and 401 is returned.
What i want to achieve is a 401 response only being made when an unauthenticated request tries to access a URL with access set to 'isAuthenticated()'. When a request is made to a URL with access set to 'permitAll', i dont want 401 to be returned, whether the request is authenticated or not.

How do I send spring csrf token from Postman rest client?

I have csrf protection in spring framework. So in each request I send csrf token in header from ajax call, which is perfectly working.
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
In ajax
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token),
xhr.setRequestHeader("username", "xxxx1"),
xhr.setRequestHeader("password", "password")
}
I haven't any idea to generate csrf token and include in header section of Postman Rest Client ? Would you please help me to send csrf token from Postman Rest Client?
The Easiest way to do this consistently so you don't have to get the token each time:
NOTE:you need to install PostMan Interceptor and activate it to have access to the browsers cookies
Create a new environment so environment variables can be stored
Create a login method with a test to store the XSRF cookie in an environment variable, in the test tab post this code
//Replace XSFR-TOKEN with your cookie name
var xsrfCookie = postman.getResponseCookie("XSRF-TOKEN");
postman.setEnvironmentVariable("xsrf-token", xsrfCookie.value);
EDIT
For anyone using the 5.5.2 postman or later you will also have to decode the cookie, and they have also provided alternative ways to obtain cookies as #Sacapuces points out
pm.environment.set("xsrf-token", decodeURIComponent(pm.cookies.get("XSRF-TOKEN")))
Now you will have an environment variable with xsrf-token in it.
Save your login method
Create the new post you want to create and in the headers add your XSRF-Token-Header Key, and the environment variable in handle bars to access it{{}}
Now before running your new request make sure you run your login, it will store the environment variable, and then when you run the actually request it will automatically append it.
I am able to send REST with csrf token by following the steps below:
The CSRF token generated automatically by spring security when you logged in. It will be shown at the response header.
The CSRF token can be used on subsequent request by setting X-CSRF-TOKEN with CSRF token on header.
Firstly you need to install PostMan Interceptor and activate it to have access to the browsers cookies.
You have to fetch the CSRF Token by making a GET Request:
Header: "XSRF-TOKEN" and Value: "Fetch"
You should see the Token in the cookie tab and can copy it (Notice: You can configure spring how the cookie should be named. Maybe your cookie has another name than "XSRF-TOKEN". Attention: You have the remove this blank char in the token from the newline)
Now make your POST Request and set the header to: Header: "X-XSRF-TOKEN" and Value: "Your copied Token without blanks"
For me works variant with adding X-CSRF-TOKEN to headers.
Please put X-CSRF-Token as key and FETCH as the value in the GET request header and you will receive the token in the response header
If you don't want to configure environment variables etc. here is the quickest solution
https://stackoverflow.com/a/49249850/3705478
I've used csrfTokenRepository() to allow spring security to generate csrf token
#EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// your code
}
}
After adding these lines of code, use GET request to generate csrf token. I've used postman and I got token in the response cookies section. Copy the token and use it in POST call.
Official documentation link :
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html

Resources