Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.wise.portal.presentation.web.filters;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.filter.OncePerRequestFilter;

/**
* Ensures the CSRF token cookie is sent to the browser. The token is loaded lazily, so on a
* request that does not otherwise read it the cookie would not be written, and the single page
* application would then have no token to send back on state-changing requests. Reading the
* token value here forces it to be generated and the cookie to be written.
*/
public class CsrfCookieFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrfToken != null) {
csrfToken.getToken();
}
filterChain.doFilter(request, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.session.Session;
import org.wise.portal.presentation.web.filters.CsrfCookieFilter;
import org.wise.portal.presentation.web.filters.GoogleOpenIdConnectFilter;
import org.wise.portal.presentation.web.filters.MicrosoftAuthenticationFailureHandler;
import org.wise.portal.presentation.web.filters.MicrosoftOpenIdConnectFilter;
Expand All @@ -79,7 +82,9 @@ public class WebSecurityConfig<S extends Session> extends WebSecurityConfigurerA

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterAfter(new CsrfCookieFilter(), CsrfFilter.class)
.addFilterAfter(openSessionInViewFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(oAuth2ClientContextFilter(), OpenSessionInViewFilter.class)
.addFilterAfter(googleOpenIdConnectFilter(), OAuth2ClientContextFilter.class)
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/portal/admin/portal/manage.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<head>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<script type="text/javascript" src="${contextPath}/<spring:theme code="jquerysource" />"></script>
<script type="text/javascript" src="${contextPath}/<spring:theme code="generalsource" />"></script>
<link rel="shortcut icon" href="${contextPath}/<spring:theme code="favicon"/>" />

<script type="text/javascript">
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/portal/admin/project/import.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<div id="importFromHubDiv" style="background:#FFF9EF; padding: 10px">
<h3>Select a WISE Project to Import</h3>
<form action="importFromHub" method="POST">
<sec:csrfInput/>
<select id="importableWISEProjects" name="importableProjectId"></select>
<button type="submit">Import</button>
</form>
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/portal/admin/project/manageallprojects.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</c:if>

<script src="${contextPath}/<spring:theme code="jquerysource"/>" type="text/javascript"></script>
<script src="${contextPath}/<spring:theme code="generalsource"/>" type="text/javascript"></script>
<script src="${contextPath}/<spring:theme code="jquerymigrate.js"/>" type="text/javascript"></script>
<script src="${contextPath}/<spring:theme code="projecttags.js"/>" type="text/javascript"></script>
<script src="${contextPath}/<spring:theme code="jqueryuisource"/>" type="text/javascript"></script>
Expand Down
24 changes: 24 additions & 0 deletions src/main/webapp/portal/javascript/general.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
// Attach the CSRF token to state changing AJAX requests sent from these portal pages.
// The server stores the token in a cookie that is readable by this script and expects
// it to be echoed back in a request header, which is how it confirms the request was
// made by the page and not forged by another site. Without this, jQuery POST requests
// on these pages would be rejected once CSRF protection is enabled.
(function () {
function getCookie(name) {
var match = document.cookie.match(new RegExp('(^|;\\s*)' + name + '=([^;]*)'));
return match ? decodeURIComponent(match[2]) : null;
}
$(document).ajaxSend(function (event, jqxhr, settings) {
var method = (settings.type || 'GET').toUpperCase();
var isStateChanging =
method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE';
if (!isStateChanging || settings.crossDomain) {
return;
}
var token = getCookie('XSRF-TOKEN');
if (token) {
jqxhr.setRequestHeader('X-XSRF-TOKEN', token);
}
});
})();

function impersonateUser(username, userType) {
$.post( "/api/login/impersonate", {username: username}).always(function( data ) {
window.location.href = `/${userType}`;
Expand Down