diff --git a/src/main/java/org/wise/portal/spring/impl/WebSecurityConfig.java b/src/main/java/org/wise/portal/spring/impl/WebSecurityConfig.java index b608d1272..7e215778a 100644 --- a/src/main/java/org/wise/portal/spring/impl/WebSecurityConfig.java +++ b/src/main/java/org/wise/portal/spring/impl/WebSecurityConfig.java @@ -85,14 +85,42 @@ protected void configure(HttpSecurity http) throws Exception { .addFilterAfter(googleOpenIdConnectFilter(), OAuth2ClientContextFilter.class) .addFilterAfter(microsoftOpenIdConnectFilter(), OAuth2ClientContextFilter.class) .addFilterAfter(authenticationProcessingFilter(), GoogleOpenIdConnectFilter.class) - .authorizeRequests().antMatchers("/api/login/impersonate") - .hasAnyRole("ADMINISTRATOR", "RESEARCHER").antMatchers("/admin/**") - .hasAnyRole("ADMINISTRATOR", "RESEARCHER").antMatchers("/author/**").hasAnyRole("TEACHER") + .authorizeRequests() + // Static assets served by the resource handlers configured in WebConfig are public + // content (portal scripts, themes and translations, the runtime engine, project + // files and project icons). They must stay reachable without signing in, now that + // unmatched requests are denied by default, otherwise the login and public preview + // pages would fail to load their assets. Student uploaded files are intentionally + // excluded so they continue to require authentication. + .antMatchers("/pages/resources/**", "/portal/javascript/**", "/portal/themes/**", + "/portal/translate/**", "/vle/**", "/curriculum/**", "/projectIcons/**").permitAll() + .antMatchers("/api/login/impersonate").hasAnyRole("ADMINISTRATOR", "RESEARCHER") + .antMatchers("/admin/**").hasAnyRole("ADMINISTRATOR", "RESEARCHER") + .antMatchers("/author/**").hasAnyRole("TEACHER") .antMatchers("/project/notifyAuthor*/**").hasAnyRole("TEACHER") - .antMatchers("/student/account/info").hasAnyRole("TEACHER").antMatchers("/student/**") - .hasAnyRole("STUDENT").antMatchers("/studentStatus").hasAnyRole("TEACHER", "STUDENT") - .antMatchers("/teacher/**").hasAnyRole("TEACHER").antMatchers("/sso/discourse") - .hasAnyRole("TEACHER", "STUDENT").antMatchers("/").permitAll(); + .antMatchers("/student/account/info").hasAnyRole("TEACHER") + .antMatchers("/student/**").hasAnyRole("STUDENT") + .antMatchers("/studentStatus").hasAnyRole("TEACHER", "STUDENT") + .antMatchers("/teacher/**").hasAnyRole("TEACHER") + .antMatchers("/sso/discourse").hasAnyRole("TEACHER", "STUDENT") + // Endpoints that must stay reachable without authentication: sign-in and its + // OAuth callbacks, account registration, account and password recovery, the + // contact form, the public home, news, library and preview content, and the + // application bootstrap configuration. Every request that does not match a rule + // above falls through to the final rule and now requires authentication, rather + // than being permitted by default. + .antMatchers("/", "/login", "/login/**", "/errors/**", "/run-survey/**", + "/previewproject.html").permitAll() + .antMatchers("/api/j_acegi_security_check", "/api/google-login", "/api/microsoft-login", + "/api/logout").permitAll() + .antMatchers("/api/student/register", "/api/student/register/questions", + "/api/teacher/register", "/api/contact").permitAll() + .antMatchers("/api/student/forgot/**", "/api/teacher/forgot/**").permitAll() + .antMatchers("/api/user/config", "/api/user/info", "/api/user/languages", + "/api/announcement", "/api/news", "/api/project/library", "/api/project/community", + "/api/config/vle", "/api/config/preview/**", "/api/run/info", "/api/runInfo", + "/api/session/renew", "/api/google-user/check-user-exists").permitAll() + .anyRequest().authenticated(); http.formLogin().loginPage("/login").permitAll(); http.logout().addLogoutHandler(wiseLogoutHandler()) .logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"));