Skip to content

Commit 959e5e9

Browse files
committed
fix CORSFilter priority
1 parent 64ce224 commit 959e5e9

3 files changed

Lines changed: 36 additions & 27 deletions

File tree

src/main/java/edu/harvard/iq/dataverse/authorization/AuthFilter.java

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
import java.util.Arrays;
1616
import java.util.Optional;
1717
import java.util.logging.Logger;
18-
import org.apache.commons.lang3.StringUtils;
1918

20-
import jakarta.annotation.Priority;
2119
import jakarta.ejb.EJB;
2220
import jakarta.inject.Inject;
2321
import jakarta.servlet.Filter;
@@ -26,16 +24,14 @@
2624
import jakarta.servlet.ServletException;
2725
import jakarta.servlet.ServletRequest;
2826
import jakarta.servlet.ServletResponse;
29-
import jakarta.servlet.annotation.WebFilter;
3027
import jakarta.servlet.http.HttpServletRequest;
3128
import jakarta.servlet.http.HttpServletResponse;
3229
import jakarta.servlet.http.HttpSession;
3330
import jakarta.ws.rs.HttpMethod;
3431

3532
import com.nimbusds.openid.connect.sdk.Prompt;
33+
import org.apache.commons.lang3.Strings;
3634

37-
@WebFilter("/*")
38-
@Priority(100) // Lower number means higher priority
3935
public class AuthFilter implements Filter {
4036

4137
private static final Logger logger = Logger.getLogger(AuthFilter.class.getCanonicalName());
@@ -54,14 +50,13 @@ public class AuthFilter implements Filter {
5450
Clock clock;
5551

5652

57-
//QDR setting for the Drupal URL
58-
private String drupalUrl;
53+
5954

6055
@Override
6156
public void init(FilterConfig filterConfig) throws ServletException {
6257
logger.fine(AuthFilter.class.getName() + "initialized. filterConfig.getServletContext().getServerInfo(): " + filterConfig.getServletContext().getServerInfo());
63-
drupalUrl = settingsService.getValueForKey(SettingsServiceBean.Key.QDRDrupalSiteURL);
64-
logger.fine("Setting Drupal URl to : " + drupalUrl);
58+
//QDR setting for the Drupal URL
59+
logger.fine("Setting Drupal URl to : " + settingsService.getValueForKey(SettingsServiceBean.Key.QDRDrupalSiteURL));
6560
}
6661

6762
@Override
@@ -72,7 +67,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse response, Fi
7267
String path = httpServletRequest.getRequestURI();
7368
String uaHeader = httpServletRequest.getHeader("user-agent");
7469
//Nagios uses a user-agent starting with check_http and we don't want to do a passive login check in that case.
75-
boolean isCheck = (uaHeader != null) && (uaHeader.contains("check_http") || StringUtils.containsIgnoreCase(uaHeader, "bot") || StringUtils.containsIgnoreCase(uaHeader, "google"));
70+
boolean isCheck = (uaHeader != null) && (uaHeader.contains("check_http") || Strings.CI.contains(uaHeader, "bot") || Strings.CI.contains(uaHeader, "google"));
7671
//boolean hasAuthToken = httpServletRequest.getParameter("key") != null) || (httpServletRequest.getParameter("token")!= null) || httpServletRequest.getHeader('X-Dataverse-key');
7772
//~QDR specific - a means to reset the passiveChecked flag so the next access will try passive login again
7873
//If the origin were configurable, this might be useful in general
@@ -94,7 +89,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse response, Fi
9489
httpServletResponse.setStatus(204);
9590
return;
9691
}
97-
if ((httpServletRequest.getMethod() == HttpMethod.GET) && !isCheck && (path.equals("/") || path.endsWith(".xhtml") && !(path.endsWith("logout.xhtml")|| path.endsWith("privateurl.xhtml") || path.contains("jakarta.faces.resource") || path.contains("/oauth2/callback")))) {
92+
if ((httpServletRequest.getMethod().equals(HttpMethod.GET)) && !isCheck && (path.equals("/") || path.endsWith(".xhtml") && !(path.endsWith("logout.xhtml")|| path.endsWith("privateurl.xhtml") || path.contains("jakarta.faces.resource") || path.contains("/oauth2/callback")))) {
9893
logger.fine("Path: " + path);
9994
String sso = httpServletRequest.getParameter("sso");
10095
//Going to /
@@ -130,7 +125,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse response, Fi
130125

131126
StringBuilder sb = new StringBuilder();
132127
for (String string : Arrays.asList(remoteAddr, requestUri, userAgent)) {
133-
sb.append(string + separator);
128+
sb.append(string).append(separator);
134129
}
135130

136131
logger.fine(sb.toString());
@@ -153,9 +148,9 @@ public void destroy() {
153148
* Create a randomized unique state string to be used while crafting the
154149
* authorization request
155150
*
156-
* @param idp
157-
* @param redirectPage
158-
* @return Random state string, composed from system time, random numbers and
151+
* @param idp the Oauth2 provider
152+
* @param redirectPage where redirects should go
153+
* @return Random state string, created from system time, random numbers, and
159154
* redirectPage parameter
160155
*/
161156
private String createState(AbstractOAuth2AuthenticationProvider idp, Optional<String> redirectPage) {
@@ -169,8 +164,7 @@ private String createState(AbstractOAuth2AuthenticationProvider idp, Optional<St
169164
+ redirectPage.map(page -> "~" + page).orElse("");
170165

171166
String encrypted = StringUtil.encrypt(base, idp.getClientSecret());
172-
final String state = idp.getId() + "~" + encrypted;
173-
return state;
167+
return idp.getId() + "~" + encrypted;
174168
}
175169

176170
}

src/main/java/edu/harvard/iq/dataverse/filter/CorsFilter.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@
1010
import edu.harvard.iq.dataverse.settings.JvmSettings;
1111
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
1212
import edu.harvard.iq.dataverse.util.ListSplitUtil;
13-
import jakarta.annotation.Priority;
1413
import jakarta.ejb.EJB;
15-
import jakarta.servlet.DispatcherType;
1614
import jakarta.servlet.Filter;
1715
import jakarta.servlet.FilterChain;
1816
import jakarta.servlet.FilterConfig;
1917
import jakarta.servlet.ServletException;
2018
import jakarta.servlet.ServletRequest;
2119
import jakarta.servlet.ServletResponse;
22-
import jakarta.servlet.annotation.WebFilter;
2320
import jakarta.servlet.http.HttpServletRequest;
2421
import jakarta.servlet.http.HttpServletResponse;
2522

@@ -35,13 +32,6 @@
3532
* The filter is applied to all paths ("/*") in the application.
3633
*/
3734

38-
@WebFilter(value = "/*", dispatcherTypes = {
39-
DispatcherType.REQUEST,
40-
DispatcherType.FORWARD,
41-
DispatcherType.ERROR,
42-
DispatcherType.ASYNC
43-
})
44-
@Priority(90) // Lower number means higher priority - run before authorization.AuthFilter
4535
public class CorsFilter implements Filter {
4636

4737
@EJB

src/main/webapp/WEB-INF/web.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,31 @@
253253
<servlet-name>edu.harvard.iq.dataverse.api.datadeposit.SWORDv2ContainerServlet</servlet-name>
254254
<url-pattern>/dvn/api/data-deposit/v1.1/swordv2/edit/*</url-pattern>
255255
</servlet-mapping>
256+
<!--
257+
Filter ordering is important!
258+
CorsFilter must run before AuthFilter to ensure CORS headers are added
259+
even if AuthFilter returns early (e.g., for /ssoreset).
260+
-->
261+
<filter>
262+
<filter-name>CorsFilter</filter-name>
263+
<filter-class>edu.harvard.iq.dataverse.filter.CorsFilter</filter-class>
264+
</filter>
265+
<filter>
266+
<filter-name>AuthFilter</filter-name>
267+
<filter-class>edu.harvard.iq.dataverse.authorization.AuthFilter</filter-class>
268+
</filter>
269+
<filter-mapping>
270+
<filter-name>CorsFilter</filter-name>
271+
<url-pattern>/*</url-pattern>
272+
<dispatcher>REQUEST</dispatcher>
273+
<dispatcher>FORWARD</dispatcher>
274+
<dispatcher>ERROR</dispatcher>
275+
<dispatcher>ASYNC</dispatcher>
276+
</filter-mapping>
277+
<filter-mapping>
278+
<filter-name>AuthFilter</filter-name>
279+
<url-pattern>/*</url-pattern>
280+
</filter-mapping>
256281
<filter>
257282
<filter-name>edu.harvard.iq.dataverse.api.datadeposit.SwordFilter</filter-name>
258283
<filter-class>edu.harvard.iq.dataverse.api.datadeposit.SwordFilter</filter-class>

0 commit comments

Comments
 (0)