spring-security: CglibAopProxy not intercepting method call for GlobalMethodSecurityConfiguration - java

I am trying to extend GlobalMethodSecurityConfiguration with the #EnableGlobalMethodSecurity annotation. I have a separate configuration class that extends WebSecurityConfigurerAdapter with the #EnableWebSecurity annotation.
If I place the #EnableGlobalMethodSecurity on my WebSecurityConfigurerAdapter and not on my GlobalMethodSecurityConfiguration class I am able to see in CglibAopProxy that the method is being intercepted and then invoked. If I remove #EnableGlobalMethodSecurity from WebSecurityConfigurerAdapter and place it on GlobalMethodSecurityConfiguration I no longer see any method interception.
Are the two configurations conflicting? Does anyone have any idea why my methods are no longer properly being invoked after configuring GlobalMethodSecurityConfiguration. I hope to implement method security by extending GlobalMethodSecurityConfiguration so I can provide my own handler and expression root.
I can provide code snippets if needed.
Thanks,
Civerooni

This was solved by the answer in the question Spring Boot: Configure custom MethodSecurityExpressionOperations?. I am not 100% sure why Autowiring my own services, registering them as beans was preventing the method intercept for happening. I suspect it was because it was using different application contexts.

Related

Spring Security deprecate the configuration class WebSecurityConfigurerAdapter

I recently updated the spring bot versions and noticed that the WebSecurityConfigurerAdapter class has been deprecated and I am going to make changes however I have a problem how can I make changes in my code.
And my question is how can I refactor such a piece of code
#Configuration
public class MyAutoConfiguration {
#Bean
#ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
public WebSecurityConfigurerAdapter myService() {
...
}
}
As you can see here I am using WebSecurityConfigurerAdapter 2 times,and what method could I use to make it work properly in the current version of Spring Configuring WebSecurity?
The recommended way of doing this is registering a SecurityFilterChain bean
you can find detailed information on how to do this in Spring Documentation.
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

Spring Boot custom annotations

In all of my projects I need the same WebSecurityConfig. So I copy the same implementation of extending WebSecurityConfigurerAdapter.
I like to add this to a common library I am using in every project and create a annotation for that.
But the annotation class cannot have a superclass.
I tried this:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Configuration
#EnableWebSecurity
public #interface EnableGlobalSecurity extends WebSecurityConfigurerAdapter {
}
Is there a better way to get this working? I just want to add my SecurityConfiguration by adding an annotation or something similar.
You should be able to just #Import your shared #Configuration class in every application that should use it.
Another way would be to create a custom auto-configuration. This way, declaring a dependency on your shared library would suffice.

Can I use #PreAuthorize in a simple class ( not a #Component)

I am trying to add control authorization in some methods using
#PreAuthorize("hasRole('ADMIN')").
Methods belong to a simple class DaoImpl implementing an interface DAO,
I add this
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
to my security config class.
for me it doesn't work, is it logic or I miss something?
The answer is no.
Spring can only enforce annotations on classes it is aware of. To make spring aware of instantiated classes it needs to either instantiate them itself, which means the class needs to be annotated with one of springs lifecycle annotations ex. #Component, #Service #RestController, or you need to instantiate them yourself and hand them over to the spring context. This can for instance be done by using the new keyword in a #Bean annotated function in a #Configuration annotated class and then return the newly created class from the #Bean annotated function.
If you create the class yourself by using the new keyword just randomly in your application, spring will have no awareness of the class and hence has no ability to intercept function calls using spring AOP and in turn enforce annotations on them like for instance #PreAuthorize

Spring security: difference between WebSecurityConfigurerAdapter and GlobalAuthenticationConfigurerAdapter

These two classes:
WebSecurityConfigurerAdapter
GlobalAuthenticationConfigurerAdapter
seem to do the same thing to me. They both provide different methods configure(...) to customize WebSecurity, such as to configure UserDetailsService. In some examples found on the internet, I saw that both classes are extended (like this one, http://ryanjbaxter.com/2015/01/06/securing-rest-apis-with-spring-boot/):
#Configuration
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {...}
and
#EnableWebSecurity
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {...}
but in some example, only WebSecurityConfigurerAdapter was needed (extended).
I am not sure about the difference between the two? What one can do that the other cannot? Or if they are both needed, then which of them is for what aspect of Spring security?
The only difference I've seen is that #EnableWebSecurity is often annotated above class that extends WebSecurityConfigurerAdapter, but not in the class that extends GlobalAuthenticationConfigurerAdapter
=============EXPERIMENT==================
I tried deleting the class that extends GlobalAuthenticationConfigurerAdapter, and carrying the code related to UserDetailsService to the class that extends WebSecurityConfigurerAdapter (See the link above for the actual code), and it still works.
Basically WebSecurityConfigurerAdapter is used to create the FilterChainProxy
refer to this docs as to GlobalAuthenticationConfigurerAdapter is used as SecurityConfigurerthat can be used to easily build in memory authentication, LDAP authentication, JDBC based authentication, adding UserDetailsService, and adding AuthenticationProvider's. refer to this docs hope this helps!

Configure RequestMappingHandlerMapping to not decode url

I have a Spring MVC 3.2.8 application with Java configuration. I want to disable url decoding as I have this issue with / in the uri. Spring 3.2.8 should fix this.
The problem is, I can't set Url decoding to false in RequestMappingHandlerMapping. I tried to override it with:
#Configuration
public class MobileWebPublicConfig extends WebMvcConfigurationSupport {
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
handlerMapping.setUrlDecode(false);
return handlerMapping;
}
}
But when I do this, it breaks my application an auto-wiring stops working.
What am I missing?
UPDATE: container is Tomcat 6, there is no stacktrace related, the app fails when trying to access an autowired element due to it being null. Commenting the configuration above makes it work fine.
The documentation for #EnableWebMvc describes three levels of customization for tailoring your configuration. You can:
Use #EnableWebMvc on its own to import the standard configuration.
Use #EnableWebMvc with configuration classes that extend WebMvcConfigurerAdapter; the subclasses will have their implemented methods called automatically to apply your changes to the standard configuration.
Don't use #EnableWebMvc, but instead make your configuration class extend WebMvcConfigurationSupport to gain full control over your configuration.
However, what the documentation does not make clear is that if you go for option 3 it will not automatically apply the methods implemented in classes that extend WebMvcConfigurerAdapter.
As others have said, we really need to see your full configuration, but if simply extending WebMvcConfigurationSupport and removing #EnableWebMvc breaks other parts of your configuration, my guess is that you are still using WebMvcConfigurerAdapter somewhere else in your config.
If this is the case, you have two options:
Rewrite all your configuration that uses WebMvcConfigurerAdapter and move the code into a single configuration class that extends WebMvcConfigurationSupport.
Extend DelegatingWebMvcConfiguration instead of WebMvcConfigurationSupport. This will give you all the standard configuration behaviour that you normally get when using #EnableWebMvc but still allow you to override methods as required. Note that in any method you override, you'll also need to call the equivalent method in super() if you want to keep the default behaviour too.
EDIT: Also make sure that you don't have #EnableWebMvc annotation somewhere since this annotation will import the original WebMvcConfigurationSupport and not the extended version.
WebMvcConfigurationSupport javadoc says
It is typically imported by adding #EnableWebMvc to an application #Configuration class. An alternative more advanced option is to extend directly from this
class and override methods as necessary remembering to add
#Configuration to the subclass and #Bean to overridden #Bean methods.

Categories

Resources