Skip to content

Commit

Permalink
Fixes #448
Browse files Browse the repository at this point in the history
  • Loading branch information
nmandrescu committed Sep 21, 2022
1 parent 7525067 commit a559d7c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.context.SecurityContextHolderFilter;

import static org.devgateway.toolkit.web.WebConstants.FORMS_BASE_PATH;

Expand All @@ -45,7 +46,7 @@ public class FormsSecurityConfig extends WebSecurityConfig {
* resources
*/
@Override
public void configure(final WebSecurity web) throws Exception {
public void configure(final WebSecurity web) {
super.configure(web);
web.ignoring().antMatchers("/img/**", "/css*/**", "/js*/**", "/assets*/**", "/favicon.ico", "/resources/**",
"/resources/public/**");
Expand Down Expand Up @@ -87,8 +88,9 @@ public AbstractRememberMeServices rememberMeServices() {
}

@Override
protected void configure(final HttpSecurity http) throws Exception {
super.configure(http);
protected void configure(final HttpSecurity http, final SecurityContextHolderFilter securityContextHolderFilter)
throws Exception {
super.configure(http, securityContextHolderFilter);

// we do not allow anyonymous token. When
// enabled this basically means any guest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.devgateway.toolkit.forms.util;

import org.apache.wicket.request.cycle.RequestCycle;

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

/**
* @author Nadejda Mandrescu
*/
public final class PageUtil {
private PageUtil() {
}

public static HttpServletRequest getHttpServletRequest() {
return (HttpServletRequest) RequestCycle.get().getRequest().getContainerRequest();
}

public static HttpServletResponse getHttpServletResponse() {
return (HttpServletResponse) RequestCycle.get().getResponse().getContainerResponse();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.wicket.request.Request;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.devgateway.toolkit.forms.util.PageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
Expand All @@ -31,6 +32,7 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

import java.util.Collection;

Expand All @@ -56,6 +58,9 @@ public class SSAuthenticatedWebSession extends AuthenticatedWebSession {
@SpringBean
private AuthenticationManager authenticationManager;

@SpringBean
private HttpSessionSecurityContextRepository securityContextRepository;

@SpringBean
private RoleHierarchy roleHierarchy;

Expand All @@ -64,7 +69,7 @@ public class SSAuthenticatedWebSession extends AuthenticatedWebSession {

/*
* (non-Javadoc)
*
*
* @see org.apache.wicket.Session#replaceSession()
*/
@Override
Expand Down Expand Up @@ -99,6 +104,11 @@ public boolean authenticate(final String username, final String password) {
Authentication authentication =
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
SecurityContextHolder.getContext().setAuthentication(authentication);

// (since Spring Security 5.7) explicitly save context, no longer done by security filter
securityContextRepository.saveContext(SecurityContextHolder.getContext(), PageUtil.getHttpServletRequest(),
PageUtil.getHttpServletResponse());

// httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
// SecurityContextHolder.getContext());
authenticated = authentication.isAuthenticated();
Expand Down Expand Up @@ -129,7 +139,7 @@ public Roles getRoles() {
/**
* Gets the Spring roles and dumps them into Wicket's {@link Roles} object,
* only if the user is signed in
*
*
* @see {@link #isSignedIn()}
* @see #addRolesFromAuthentication(Roles, Authentication)
* @param roles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ public TestAddress getById(final Long aLong) {
return null;
}

@Override
public TestAddress getReferenceById(final Long aLong) {
return null;
}

@Override
public List findAll(Example example, Sort sort) {
return null;
Expand Down Expand Up @@ -192,6 +197,11 @@ public boolean exists(Example example) {
return false;
}

@Override
public boolean exists(final Specification<TestAddress> spec) {
return false;
}

@Override
public <S extends TestAddress, R> R findBy(final Example<S> example,
final Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction) {
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<liquibase.version>4.7.1</liquibase.version>
<spring.boot.version>2.6.3</spring.boot.version>
<spring.boot.version>2.7.3</spring.boot.version>
<derby.version>10.14.2.0</derby.version>
<poi.version>4.0.1</poi.version>
<maven-checkstyle-plugin.version>3.1.2</maven-checkstyle-plugin.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.context.SecurityContextHolderFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;

Expand All @@ -49,7 +51,7 @@
// them overlayed, it must pick that one first)
@PropertySource("classpath:allowedApiEndpoints.properties")
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public class WebSecurityConfig {

@Autowired
protected CustomJPAUserDetailsService customJPAUserDetailsService;
Expand Down Expand Up @@ -78,30 +80,42 @@ public HttpSessionSecurityContextRepository httpSessionSecurityContextRepository
}

@Bean
public SecurityContextPersistenceFilter securityContextPersistenceFilter() {
final SecurityContextPersistenceFilter securityContextPersistenceFilter =
new SecurityContextPersistenceFilter(httpSessionSecurityContextRepository());
return securityContextPersistenceFilter;
public SecurityContextHolderFilter securityContextHolderFilter(
HttpSessionSecurityContextRepository securityContextRepository) {
SecurityContextHolderFilter securityContextHolderFilter =
new SecurityContextHolderFilter(securityContextRepository);
return securityContextHolderFilter;
}

@Override
public void configure(final WebSecurity web) throws Exception {
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return this::configure;
}

public void configure(final WebSecurity web) {
web.httpFirewall(allowUrlEncodedSlashHttpFirewall())
.ignoring().antMatchers(allowedApiEndpoints).and()
.ignoring().antMatchers(
FORMS_BASE_PATH + "/login",
FORMS_BASE_PATH + "/forgotPassword/**");
}

@Override
protected void configure(final HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain filterChain(final HttpSecurity http,
final SecurityContextHolderFilter securityContextHolderFilter) throws Exception {
this.configure(http, securityContextHolderFilter);
return http.build();
}

protected void configure(final HttpSecurity http, final SecurityContextHolderFilter securityContextHolderFilter)
throws Exception {
http.authorizeRequests().expressionHandler(webExpressionHandler()) // inject role hierarchy
.antMatchers(FORMS_BASE_PATH + "/monitoring/**").access("hasRole('ROLE_ADMIN')")
.antMatchers(FORMS_BASE_PATH + "/**").authenticated().and()
.formLogin().loginPage(FORMS_BASE_PATH + "/login").permitAll().and()
.requestCache().and().logout().permitAll().and()
.sessionManagement().and().csrf().disable();
http.addFilter(securityContextPersistenceFilter());
http.addFilter(securityContextHolderFilter);
}

/**
Expand All @@ -128,13 +142,16 @@ RoleHierarchy roleHierarchy() {
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}

@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customJPAUserDetailsService).passwordEncoder(passwordEncoder);
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(customJPAUserDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder);
return authenticationProvider;
}
}

0 comments on commit a559d7c

Please sign in to comment.