Class DSpaceCsrfTokenRepository
- java.lang.Object
-
- org.dspace.app.rest.security.DSpaceCsrfTokenRepository
-
- All Implemented Interfaces:
org.springframework.security.web.csrf.CsrfTokenRepository
public class DSpaceCsrfTokenRepository extends Object implements org.springframework.security.web.csrf.CsrfTokenRepository
This is a custom Spring Security CsrfTokenRepository which supports *cross-domain* CSRF protection (allowing the client and backend to be on different domains). It's inspired by https://stackoverflow.com/a/33175322This also borrows heavily from Spring Security's CookieCsrfTokenRepository: https://github.com/spring-projects/spring-security/blob/5.2.x/web/src/main/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.java How it works: 1. Backend generates XSRF token & stores in a *server-side* cookie named DSPACE-XSRF-COOKIE. By default, this cookie is not readable to JS clients (HttpOnly=true). But, it is returned (by user's browser) on every subsequent request to backend. See "saveToken()" method below. 2. At the same time, backend also sends the generated XSRF token in a header named DSPACE-XSRF-TOKEN to client. See "saveToken()" method below. 3. Client MUST look for DSPACE-XSRF-TOKEN header in a response from backend. If found, the client MUST store/save this token for later request(s). For Angular UI, this task is performed by the XsrfInterceptor. 4. Whenever the client is making a mutating request (e.g. POST, PUT, DELETE, etc), the XSRF token is REQUIRED to be sent back in the X-XSRF-TOKEN header. * NOTE: non-mutating requests (e.g. GET, HEAD) do not check for an XSRF token. This is default behavior in Spring Security 5. On backend, the X-XSRF-TOKEN header is received & compared to the current value of the *server-side* cookie named DSPACE-XSRF-COOKIE. If tokens match, the request is accepted. If tokens don't match a 403 is returned. This is done automatically by Spring Security. In summary, the XSRF token is ALWAYS sent to/from the client & backend via *headers*. This is what allows the client and backend to be on different domains. The server-side cookie named DSPACE-XSRF-COOKIE is (usually) not accessible to the client. It only exists to allow the server-side to remember the currently active XSRF token, so that it can validate the token sent (by the client) in the X-XSRF-TOKEN header.
-
-
Constructor Summary
Constructors Constructor Description DSpaceCsrfTokenRepository()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description org.springframework.security.web.csrf.CsrfTokengenerateToken(javax.servlet.http.HttpServletRequest request)StringgetCookiePath()Get the path that the CSRF cookie will be set to.org.springframework.security.web.csrf.CsrfTokenloadToken(javax.servlet.http.HttpServletRequest request)voidsaveToken(org.springframework.security.web.csrf.CsrfToken token, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)This method has been modified for DSpace.voidsetCookieDomain(String cookieDomain)Sets the domain of the cookie that the expected CSRF token is saved to and read from.voidsetCookieHttpOnly(boolean cookieHttpOnly)Sets the HttpOnly attribute on the cookie containing the CSRF token.voidsetCookieName(String cookieName)Sets the name of the cookie that the expected CSRF token is saved to and read from.voidsetCookiePath(String path)Set the path that the Cookie will be created with.voidsetHeaderName(String headerName)Sets the name of the HTTP header that should be used to provide the token.voidsetParameterName(String parameterName)Sets the name of the HTTP request parameter that should be used to provide a token.static DSpaceCsrfTokenRepositorywithHttpOnlyFalse()Factory method to conveniently create an instance that hassetCookieHttpOnly(boolean)set to false.
-
-
-
Method Detail
-
generateToken
public org.springframework.security.web.csrf.CsrfToken generateToken(javax.servlet.http.HttpServletRequest request)
- Specified by:
generateTokenin interfaceorg.springframework.security.web.csrf.CsrfTokenRepository
-
saveToken
public void saveToken(org.springframework.security.web.csrf.CsrfToken token, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)This method has been modified for DSpace.It now uses ResponseCookie to build the cookie, so that the "SameSite" attribute can be applied.
It also sends the token (if not empty) in both the cookie and the custom "DSPACE-XSRF-TOKEN" header
- Specified by:
saveTokenin interfaceorg.springframework.security.web.csrf.CsrfTokenRepository- Parameters:
token- current tokenrequest- current requestresponse- current response
-
loadToken
public org.springframework.security.web.csrf.CsrfToken loadToken(javax.servlet.http.HttpServletRequest request)
- Specified by:
loadTokenin interfaceorg.springframework.security.web.csrf.CsrfTokenRepository
-
setParameterName
public void setParameterName(String parameterName)
Sets the name of the HTTP request parameter that should be used to provide a token.- Parameters:
parameterName- the name of the HTTP request parameter that should be used to provide a token
-
setHeaderName
public void setHeaderName(String headerName)
Sets the name of the HTTP header that should be used to provide the token.- Parameters:
headerName- the name of the HTTP header that should be used to provide the token
-
setCookieName
public void setCookieName(String cookieName)
Sets the name of the cookie that the expected CSRF token is saved to and read from.- Parameters:
cookieName- the name of the cookie that the expected CSRF token is saved to and read from
-
setCookieHttpOnly
public void setCookieHttpOnly(boolean cookieHttpOnly)
Sets the HttpOnly attribute on the cookie containing the CSRF token. Defaults totrue.- Parameters:
cookieHttpOnly-truesets the HttpOnly attribute,falsedoes not set it
-
withHttpOnlyFalse
public static DSpaceCsrfTokenRepository withHttpOnlyFalse()
Factory method to conveniently create an instance that hassetCookieHttpOnly(boolean)set to false.- Returns:
- an instance of CookieCsrfTokenRepository with
setCookieHttpOnly(boolean)set to false
-
setCookiePath
public void setCookiePath(String path)
Set the path that the Cookie will be created with. This will override the default functionality which uses the request context as the path.- Parameters:
path- the path to use
-
getCookiePath
public String getCookiePath()
Get the path that the CSRF cookie will be set to.- Returns:
- the path to be used.
-
setCookieDomain
public void setCookieDomain(String cookieDomain)
Sets the domain of the cookie that the expected CSRF token is saved to and read from.- Parameters:
cookieDomain- the domain of the cookie that the expected CSRF token is saved to and read from- Since:
- 5.2
-
-