Skip to content

Commit

Permalink
Removes global state from CSRF components (playframework#6854)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcospereira authored and gmethvin committed Jan 25, 2017
1 parent fcf8319 commit fab982b
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 83 deletions.
Expand Up @@ -7,6 +7,7 @@

import javax.inject.Inject;

import play.api.http.SessionConfiguration;
import play.api.libs.crypto.CSRFTokenSigner;
import play.api.mvc.Session;
import play.mvc.Action;
Expand All @@ -19,25 +20,29 @@
public class AddCSRFTokenAction extends Action<AddCSRFToken> {

private final CSRFConfig config;
private final SessionConfiguration sessionConfiguration;
private final CSRF.TokenProvider tokenProvider;
private final CSRFTokenSigner tokenSigner;

@Inject
public AddCSRFTokenAction(CSRFConfig config, CSRF.TokenProvider tokenProvider, CSRFTokenSigner tokenSigner) {
public AddCSRFTokenAction(CSRFConfig config, SessionConfiguration sessionConfiguration, CSRF.TokenProvider tokenProvider, CSRFTokenSigner tokenSigner) {
this.config = config;
this.sessionConfiguration = sessionConfiguration;
this.tokenProvider = tokenProvider;
this.tokenSigner = tokenSigner;
}

private final CSRF.Token$ Token = CSRF.Token$.MODULE$;
private final CSRFAction$ CSRFAction = CSRFAction$.MODULE$;

@Override
public CompletionStage<Result> call(Http.Context ctx) {

CSRFActionHelper csrfActionHelper = new CSRFActionHelper(sessionConfiguration, config, tokenSigner);

play.api.mvc.Request<RequestBody> request =
CSRFAction.tagRequestFromHeader(ctx.request()._underlyingRequest(), config, tokenSigner);
csrfActionHelper.tagRequestFromHeader(ctx.request()._underlyingRequest());

if (CSRFAction.getTokenToValidate(request, config, tokenSigner).isEmpty()) {
if (csrfActionHelper.getTokenToValidate(request).isEmpty()) {
// No token in header and we have to create one if not found, so create a new token
String newToken = tokenProvider.generateToken();

Expand All @@ -46,7 +51,7 @@ public CompletionStage<Result> call(Http.Context ctx) {
ctx.args.put(Token.NameRequestTag(), config.tokenName());

// Create a new Scala RequestHeader with the token
request = CSRFAction.tagRequest(request, new CSRF.Token(config.tokenName(), newToken));
request = csrfActionHelper.tagRequest(request, new CSRF.Token(config.tokenName(), newToken));

// Also add it to the response
if (config.cookieName().isDefined()) {
Expand Down
Expand Up @@ -8,6 +8,7 @@

import javax.inject.Inject;

import play.api.http.SessionConfiguration;
import play.api.libs.crypto.CSRFTokenSigner;
import play.api.mvc.RequestHeader;
import play.api.mvc.Session;
Expand All @@ -20,34 +21,37 @@
public class RequireCSRFCheckAction extends Action<RequireCSRFCheck> {

private final CSRFConfig config;
private final SessionConfiguration sessionConfiguration;
private final CSRF.TokenProvider tokenProvider;
private final CSRFTokenSigner crypto;
private final CSRFTokenSigner tokenSigner;
private final Injector injector;

@Inject
public RequireCSRFCheckAction(CSRFConfig config, CSRF.TokenProvider tokenProvider, CSRFTokenSigner csrfTokenSigner, Injector injector) {
public RequireCSRFCheckAction(CSRFConfig config, SessionConfiguration sessionConfiguration, CSRF.TokenProvider tokenProvider, CSRFTokenSigner csrfTokenSigner, Injector injector) {
this.config = config;
this.sessionConfiguration = sessionConfiguration;
this.tokenProvider = tokenProvider;
this.crypto = csrfTokenSigner;
this.tokenSigner = csrfTokenSigner;
this.injector = injector;
}

private final CSRFAction$ CSRFAction = CSRFAction$.MODULE$;

@Override
public CompletionStage<Result> call(Http.Context ctx) {
RequestHeader request = CSRFAction.tagRequestFromHeader(ctx._requestHeader(), config, crypto);

CSRFActionHelper csrfActionHelper = new CSRFActionHelper(sessionConfiguration, config, tokenSigner);

RequestHeader request = csrfActionHelper.tagRequestFromHeader(ctx._requestHeader());
// Check for bypass
if (!CSRFAction.requiresCsrfCheck(request, config)) {
if (!csrfActionHelper.requiresCsrfCheck(request)) {
return delegate.call(ctx);
} else {
// Get token from cookie/session
Option<String> headerToken = CSRFAction.getTokenToValidate(request, config, crypto);
Option<String> headerToken = csrfActionHelper.getTokenToValidate(request);
if (headerToken.isDefined()) {
String tokenToCheck = null;

// Get token from query string
Option<String> queryStringToken = CSRFAction.getHeaderToken(request, config);
Option<String> queryStringToken = csrfActionHelper.getHeaderToken(request);
if (queryStringToken.isDefined()) {
tokenToCheck = queryStringToken.get();
} else {
Expand Down

0 comments on commit fab982b

Please sign in to comment.