SEBSERV-342 fixed with filter
This commit is contained in:
parent
ec4215b944
commit
340a61504d
5 changed files with 83 additions and 15 deletions
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue