How to import security configuration class from another module - spring-boot

I want to develop my security config in separate module and add it as dependency in main app. so I wrote a very simple test project as parent which has 2 child modules: security-module and app
security-module has only one configuration class as follow:
#Configuration
#EnableWebSecurity
public class Security extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().
withUser("h").
password("1").
roles("admin");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().disable();
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/", "/login").permitAll()
.antMatchers("/static/**").permitAll()
.anyRequest().authenticated();
}
}
In app module, I have a SecurityConfig class which is as follow:
#Configuration
#Import({
Security.class
})
public class SecurityConfig{
}
also the resources directory is as follow:
The problem is HttpSecurity object, configured in Security class, is not registered completely. Said completely cause if I add anyRequest().pertmitAll() in Security class, then all is good, but now for any request i get 403 error, even when I call resources explicity like localhost:8080/dash.html
I also tried extending Security as follow in SecurityConfig:
#Configuration
public class SecurityConfig extends Security{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
}
but nothing changed.
How can I fix this problem?

Related

Spring boot (v2.6.7) security with JWT, web.ignoring() is working but not antMatchers permitAll()

I migrated Spring boot from 2.1.5 to 2.6.7. Now the security configuration is throwing a warning about antMatchers in web.ignoring in the WebSecurity configuration lines, although it works correctly. Upon moving the web.ignoring to antMatchers permitAll() in httpConfiguration, the warning goes away but the urls are no longer permitted.
I am also using JWT and it looks like the JWT filters are kicking in and not honoring the httpConfiguration. I am really confused as to how to configure this. I am including the before and after here.
WORKS WITH WARNING:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
#Override
public void init(WebSecurity web) throws Exception {
super.init(web);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.debug("**********************SECURITY INITALIZE NORMAL#######################################");
http.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.addFilter(new JWTAuthorizationFilter(authenticationManager(), getApplicationContext()))
.addFilter(new JWTAuthenticationFilter(authenticationManager(), getApplicationContext()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs/**");
}
}
DOES NOT WORK:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
#Override
public void init(WebSecurity web) throws Exception {
super.init(web);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.debug("**********************SECURITY INITALIZE NORMAL#######################################");
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/v2/api-docs/**").permitAll() // ADDED LINE
.anyRequest().authenticated().and()
.addFilter(new JWTAuthorizationFilter(authenticationManager(), getApplicationContext()))
.addFilter(new JWTAuthenticationFilter(authenticationManager(), getApplicationContext()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(WebSecurity web) throws Exception {
//web.ignoring().antMatchers("/v2/api-docs/**");
}
}
Looks like somehow the configuration breaks when using http security versus web security. I have tried many of the suggestions but nothing seems to work.
Can someone familiar with Spring Boot Security in 2.6.7 with JWT filters please suggest what I am doing wrong?

Spring REST security - Secure different URLs differently for different user

I am trying to provide security using spring boot security to the REST multiple endpoints with user wise but it is working for only one endpoint which depend on order and others don't work. Please suggest the solution. below my code replica
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Configuration
#Order(0)
public static class Api1WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/getEmployees/").authenticated()
.and().httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("bill").password("gates").roles("USER");
}
}
#Configuration
#Order(1)
public static class Api2WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/getEmpId/).authenticated().and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("raj").password("simran").roles("USER");
}
}

Multiple authentication provider for specific url - Spring Boot Security

In Spring security I want to use Basic authentication for urls starting with api/** LDAP Rest Authentication for urls starting with /ldap/. The current code i have also allows ldap/ with basic authentication.
The question comes even if i use them as separate AuthenticationProviders like LdapAuthProvider and BasicAuthProvider how can i use it to point to the specific urls
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Configuration
#Order(1)
public class BasicAuthenticationProvider extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/swagger-ui*", "/info", "/health").permitAll()
.and().authorizeRequests().antMatchers("/order/**").fullyAuthenticated()
.and().httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable()
.anonymous().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(inMemoryUserDetailsManager());
}
}
#Configuration
#Order(2)
public class LdapAuthenticationProvider extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/ldap/**").fullyAuthenticated().and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.ldapAuthentication() code here......
}
}
}
As far as I understand, You have multiple entry points in one application and there are different types of users that can access different portions of the application.
You should look at this Baeldung tutorial: Multiple Entry Points in Spring Security

Spring boot and spring security multiple login pages

#EnableWebSecurity
public class MultiHttpSecurityConfig {
#Configuration
#Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/my/**", "/account/**").access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
.and().formLogin().loginPage("/login");
}
}
#Configuration
#Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin().loginPage("/adminlogin");
}
}
}
This is supposed be two different login forms. My problem is that the one with the highest order /adminlogin is not displayed. I have idea why? Please help. The code is from Spring boot - how to configure multiple login pages?
Following Sofia's suggestion I tried this:
#Configuration
#Order(2)
public static class UserConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new AntPathRequestMatcher("/my/**"))
.csrf().disable()
.authorizeRequests().antMatchers("/my/**").access("hasRole('ROLE_USER')")
.and().formLogin().loginPage("/login");
}
}
#Configuration
#Order(1)
public static class AdminConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new AntPathRequestMatcher("/admin/**"))
.csrf().disable()
.authorizeRequests().antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin().loginPage("/adminlogin");
}
}
But in both cases /login is called
I reckon that the reason why your admin login is not activating is because: first, it is NOT higher in priority.
#Order defines the sort order for an annotated component.
The value is optional and represents an order value as defined in the Ordered interface. Lower values have higher priority. The default value is Ordered.LOWEST_PRECEDENCE, indicating lowest priority (losing to any other specified order value).
Second, according to HttpSecurity's Javadoc:
A HttpSecurity is similar to Spring Security's XML element in the namespace configuration. It allows configuring web based security for specific http requests. By default it will be applied to all requests, but can be restricted using requestMatcher(RequestMatcher) or other similar methods.
So try restricting the HttpSecurity object to activate for your admin pages by first configuring the requestMatcher such that:
http
.requestMatcher(new AntPathRequestMatcher("/admin/**"))
.csrf().disable()
.authorizeRequests().antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin().loginPage("/adminlogin");
I solved it using request matcher:
#Configuration
#EnableWebSecurity
public class AllConfig extends WebSecurityConfigurerAdapter {
#Autowired
MyUserDeatailService myuserDetailsService;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
#Bean
public static BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(4);
}
#Bean
public AuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(myuserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
#Bean
public static AuthenticationFailureHandler customAuthenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
#Configuration
#Order(1)
public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcher("/admin/**"))
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and().formLogin()
.loginPage("/admin/adminlogin").permitAll().usernameParameter("username")
.passwordParameter("password").defaultSuccessUrl("/admin/AdminDashBoard")
.failureHandler(customAuthenticationFailureHandler()).and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/home").and()
.exceptionHandling().accessDeniedPage("/403");
}
}
#Configuration
#Order(2)
public static class UserSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcher("/user/**"))
.csrf().disable()
.authorizeRequests()
.antMatchers("/user/**").access("hasRole('ROLE_USER')").and().formLogin()
.loginPage("/user/userlogin").permitAll().usernameParameter("username")
.passwordParameter("password").defaultSuccessUrl("/user/UserDashBoard")
.failureHandler(customAuthenticationFailureHandler()).and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").and()
.exceptionHandling().accessDeniedPage("/403");
}
}
}

Spring Security PreAuthorize Custom Method Bean resolver is not registered?

Im just learning Spring, going through tutorials and testing possibilities. One of my goals is to secure a Service Method using a Custom Method and the PreAuthorize annotation. Unfortunaly the Bean holding the custom Method cannot be resolved and I dont know why. Maybe someone can see the error at first sight.
Bean holding the custom Method:
#Component("mySecurityService")
public class MySecurityService {
public boolean hasPermission() {
return true; //simple implementation just to look if has permission is called
}
}
Service to be Secured:
public interface OrderService {
#PreAuthorize("#mySecurityService.hasPermission()")
public AllOrdersEvent requestAllOrders(RequestAllOrdersEvent requestAllCurrentOrdersEvent);
public OrderDetailsEvent requestOrderDetails(RequestOrderDetailsEvent requestOrderDetailsEvent);
public OrderStatusEvent requestOrderStatus(RequestOrderStatusEvent requestOrderStatusEvent);
public OrderCreatedEvent createOrder(CreateOrderEvent event);
public OrderUpdatedEvent setOrderPayment(SetOrderPaymentEvent setOrderPaymentEvent);
public OrderDeletedEvent deleteOrder(DeleteOrderEvent deleteOrderEvent);
}
Java Security Config:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("letsnosh").password("noshing").roles("USER");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean(name = "mySecurityService")
MySecurityService createSecurityService(){return new MySecurityService();}
#Override
protected void configure(HttpSecurity http) throws Exception {
/*
http.authorizeUrls()
.antMatchers("/aggregators*//**//**").hasRole("USER")
.anyRequest().anonymous()
.and()
.httpBasic();
*/
}
}
Error:
No bean resolver registered in the context to resolve access to bean 'mySecurityService'
Hello I solved the problem. It was connected to the Version of Spring Security.
I got the Version from the official Spring Rest Tutotrial : 3.2.0.M2
In this version I had to declare the Security Context as follows:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("letsnosh").password("noshing").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeUrls()
.antMatchers("/aggregators/**").hasRole("USER")
.anyRequest().anonymous()
.and()
.httpBasic();
}
}
Here the error was thrown.
But using a newer Version of Spring Security: 3.2.5.RELEASE
I could declare the Config this way:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeUrls()
.antMatchers("/aggregators*//**//**").hasRole("USER")
.anyRequest().anonymous()
.and()
.httpBasic();
}
And the bean could be resolved, using either #Component Annotaions directly on the MySecurityService class or #Bean annotations on a config class method which returns a MySecurityService instance.

Resources