SEBSERV-342 fixed with filter

This commit is contained in:
anhefti 2023-03-30 12:13:02 +02:00
parent ec4215b944
commit 340a61504d
5 changed files with 83 additions and 15 deletions

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2023 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package ch.ethz.seb.sebserver.gui;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
@Lazy
@Component
@GuiProfile
public class CrossOriginIsolationFilter implements Filter {
private static final String SAME_ORIGIN = "same-origin";
private static final String REQUIRE_CORP = "require-corp";
private static final String CROSS_ORIGIN_OPENER_POLICY = "Cross-Origin-Opener-Policy";
private static final String CROSS_ORIGIN_EMBEDDER_POLICY = "Cross-Origin-Embedder-Policy";
private final String adminEndpoint;
private final String examEndpoint;
public CrossOriginIsolationFilter(
@Value("${sebserver.webservice.api.exam.endpoint:/exam-api}") final String examEndpoint,
@Value("${sebserver.webservice.api.admin.endpoint:/admin-api/v1}") final String adminEndpoint) {
this.adminEndpoint = adminEndpoint;
this.examEndpoint = examEndpoint;
}
@Override
public void doFilter(
final ServletRequest request,
final ServletResponse response,
final FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
chain.doFilter(request, response);
return;
}
processResponse((HttpServletRequest) request, (HttpServletResponse) response);
chain.doFilter(request, response);
}
protected void processResponse(final HttpServletRequest request, final HttpServletResponse response) {
final String url = request.getRequestURI();
if (url.startsWith(this.adminEndpoint) || url.startsWith(this.examEndpoint)) {
return;
}
response.setHeader(CROSS_ORIGIN_EMBEDDER_POLICY, REQUIRE_CORP);
response.setHeader(CROSS_ORIGIN_OPENER_POLICY, SAME_ORIGIN);
}
}

View file

@ -16,6 +16,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@ -30,6 +31,8 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private InstitutionalAuthenticationEntryPoint institutionalAuthenticationEntryPoint;
@Autowired
private CrossOriginIsolationFilter crossOriginIsolationFilter;
@Value("${sebserver.gui.entrypoint:/gui}")
private String guiEntryPoint;
@ -84,7 +87,10 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
.logout().disable()
.headers().frameOptions().disable()
.and()
.csrf().disable();
.csrf()
.disable()
// TODO Set filter to dedicated URL
.addFilterBefore(this.crossOriginIsolationFilter, ChannelProcessingFilter.class);
}
}

View file

@ -78,7 +78,6 @@ public class ProctoringServlet extends HttpServlet {
log.error("Failed to get proctoring window script for data: {}", proctoringData);
resp.getOutputStream().println("Failed to get proctoring window script");
} else {
RAPConfiguration.setCORS(resp);
resp.getOutputStream().println(script);
}
}
@ -87,7 +86,6 @@ public class ProctoringServlet extends HttpServlet {
protected void doOptions(final HttpServletRequest req, final HttpServletResponse resp)
throws ServletException, IOException {
RAPConfiguration.setCORS(resp);
resp.setStatus(HttpServletResponse.SC_OK);
}

View file

@ -125,8 +125,6 @@ public class RAPConfiguration implements ApplicationConfiguration {
final EntryPointService entryPointService = webApplicationContext
.getBean(EntryPointService.class);
entryPointService.loadProctoringView(parent);
final HttpServletResponse response = RWT.getResponse();
setCORS(response);
} else {
final HttpServletResponse response = RWT.getResponse();
response.setStatus(HttpStatus.FORBIDDEN.value());
@ -136,16 +134,6 @@ public class RAPConfiguration implements ApplicationConfiguration {
}
}
// https://developer.chrome.com/blog/enabling-shared-array-buffer/#cross-origin-isolation
public static final void setCORS(final HttpServletResponse resp) {
// resp.addHeader("Access-Control-Allow-Origin", "*");
// resp.setHeader("Access-Control-Allow-Methods", "GET");
// resp.setHeader("Vary", "Origin");
resp.addHeader("Cross-Origin-Embedder-Policy", "require-corp");
resp.addHeader("Cross-Origin-Opener-Policy", "same-origin");
}
public static final class RAPSpringEntryPointFactory implements EntryPointFactory {
private boolean initialized = false;

View file

@ -195,6 +195,9 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
return false;
}
// TODO check if this is needed. If not remove it.
// This gets called many times for a page load
try {
final ResponseEntity<String> forEntity =
this.restTemplate.getForEntity(this.currentUserURI, String.class);