My application has both a GlobalMethodSecurityConfiguration and a WebSecurityConfigurerAdapter configuration classes. My implementations are given below:
My GlobalMethodSecurityConfiguration implementation:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Override
protected AuthenticationManager authenticationManager() {
AuthenticationManager authenticationManager = new ProviderManager();
return authenticationManager;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(permissionEvaluator());
return expressionHandler;
}
@Bean
public ApplicationPermissionEvaluator permissionEvaluator() {
return new ApplicationPermissionEvaluator(permissionMap());
}
private Map<String, Permission> permissionMap() {
Map<String, Permission> map = new HashMap<>();
map.put("CurriculumService:findCurriculumIsAllowed", curriculumByIdOwnerPermission());
map.put("CurriculumService:updateCurriculumIsAllowed", curriculumOwnerPermission());
return map;
}
@Bean(autowire=Autowire.BY_NAME)
public CurriculumByIdOwnerPermission curriculumByIdOwnerPermission() {
return new CurriculumByIdOwnerPermission();
}
@Bean(autowire=Autowire.BY_NAME)
public CurriculumOwnerPermission curriculumOwnerPermission() {
return new CurriculumOwnerPermission();
}
}
and my WebSecurityConfigurerAdapter implementation:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//@formatter:off
http
//.csrf().disable()
.exceptionHandling().authenticationEntryPoint(delegatingAuthenticationEntryPoint())
.and().formLogin()
.loginProcessingUrl("/signin")
.loginPage("/signin")
.failureUrl("/signin?login_error=t")
.defaultSuccessUrl("/dashboard", Boolean.TRUE)
.and().logout()
.logoutUrl("/resources/j_spring_security_logout")
.logoutSuccessUrl("/signin")
.and().authorizeRequests()
.accessDecisionManager(accessDecisionManager())
.antMatchers("/preference/sendPasswordReset/**", "/preference/passwordReset/**", "/preference/activateEmail/**", "/preference/resendActivationEmail/**").permitAll()
.antMatchers("/preference/**").access("hasAnyRole('ROLE_BASIC_CHILDMINDER', 'ROLE_BASIC_FAMILY')")
.antMatchers("/dashboard").access("hasAnyRole('ROLE_BASIC_CHILDMINDER', 'ROLE_BASIC_FAMILY')")
.antMatchers("/curriculum/**").access("hasRole('ROLE_BASIC_CHILDMINDER')")
.antMatchers("/advertisement/**/view/**").permitAll()
.antMatchers("/advertisement/family/**").access("hasRole('ROLE_BASIC_FAMILY')")
.antMatchers("/advertisement/childminder/**").access("hasRole('ROLE_BASIC_CHILDMINDER')")
.antMatchers("/resources/**", "/**").permitAll();
//@formatter:on
super.configure(http);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
@Bean
public MemberUserDetailsService userDetailsService() {
return new MemberUserDetailsService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder;
}
@Bean
public SessionRegistryImpl sessionRegistry() {
SessionRegistryImpl sessionRegistry = new SessionRegistryImpl();
return sessionRegistry;
}
@Bean
public AffirmativeBased accessDecisionManager() {
AffirmativeBased accessDecisionManager = new AffirmativeBased(accessDecisionVoters());
return accessDecisionManager;
}
public List<AccessDecisionVoter> accessDecisionVoters() {
List<AccessDecisionVoter> accessDecisionVoters = new ArrayList<>();
accessDecisionVoters.add(roleHierarchyVoter());
accessDecisionVoters.add(webExpressionVoter());
return accessDecisionVoters;
}
@Bean
public WebExpressionVoter webExpressionVoter() {
WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
webExpressionVoter.setExpressionHandler(defaultWebSecurityExpressionHandler());
return webExpressionVoter;
}
@Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
return defaultWebSecurityExpressionHandler;
}
@Bean
public RoleHierarchyVoter roleHierarchyVoter() {
RoleHierarchyVoter roleHierarchyVoter = new RoleHierarchyVoter(roleHierarchy());
return roleHierarchyVoter;
}
@Bean
public RoleHierarchyImpl roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
//@formatter:off
roleHierarchy.setHierarchy(
"ROLE_ADMINISTRATOR > ROLE_MODERATOR\n" +
"ROLE_MODERATOR > ROLE_SUBSCRIBED_FAMILY\n" +
"ROLE_MODERATOR > ROLE_SUBSCRIBED_CHILDMINDER\n" +
"ROLE_SUBSCRIBED_FAMILY > ROLE_BASIC_FAMILY\n" +
"ROLE_SUBSCRIBED_CHILDMINDER > ROLE_BASIC_CHILDMINDER");
//@formatter:on
return roleHierarchy;
}
@Bean
public DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() {
DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint = new DelegatingAuthenticationEntryPoint(map());
delegatingAuthenticationEntryPoint.setDefaultEntryPoint(loginUrlAuthenticationEntryPoint());
return delegatingAuthenticationEntryPoint;
}
public LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map() {
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = new LinkedHashMap<>();
map.put(ajaxRequestMatcher(), ajaxAuthenticationEntryPoint());
return map;
}
@Bean
public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint() {
LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/signin");
return loginUrlAuthenticationEntryPoint;
}
@Bean
public AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint() {
AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint = new AjaxAuthenticationEntryPoint();
return ajaxAuthenticationEntryPoint;
}
@Bean
public AjaxRequestMatcher ajaxRequestMatcher() {
AjaxRequestMatcher ajaxRequestMatcher = new AjaxRequestMatcher();
return ajaxRequestMatcher;
}
@Bean
public RequestDataValueProcessor requestDataValueProcessor() {
return new CsrfRequestDataValueProcessor();
}
}
I am not sure how to configure the authentication manager. Is the following a correct way of proceeding?
@Override
protected AuthenticationManager authenticationManager() {
AuthenticationManager authenticationManager = new ProviderManager();
return authenticationManager;
}
Any input welcome...
When using Java configuration, the way to define multiple security realms is to have multiple @Configuration classes that extend the WebSecurityConfigurerAdapter base class – each with its own security configuration. These classes can be static and placed inside the main config.
You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class. NOTE: If you don't want to change your current code, you should keep Spring Boot version lower than 2.7. 0 or Spring Security version older than 5.7. 1.
In Spring Boot 2, if we want our own security configuration, we can simply add a custom WebSecurityConfigurerAdapter. This will disable the default auto-configuration and enable our custom security configuration. Spring Boot 2 also uses most of Spring Security's defaults.
anyRequest(). authenticated() will restrict the access for any other endpoint other than PUBLIC_URL, and the user must be authenticated.
I was looking for a way to do this too. The following worked for me:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
protected void configureGlobal (AuthenticationManagerBuilder auth) {
// Configure auth mgr
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// Configure expression handler
}
@Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Configure HTTP security
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With