How to debug Spring Security authorization annotations? - spring

I have spring security application in which want to enable annotations security (pre and post authorization).
I also have small sample application in which i have implemented it already. Everything works.
But moving configs to main applications failed. There is no errors in console. But annotations do not work. It seems, they are not readed at all.
All configuration and component versions are completely the same.
There are
<security:global-method-security secured-annotations="enabled" />
records in security-context and servlet-context.
But neither #Controller methods no #Service methods are secured with annotation in main application.
How can i debug it?
Solved!
After switch from < global-method-security secured-annotations="enabled" /> to
pre/post annotations works fine.

You can add to your application.yaml:
logging.level.org.springframework.security: DEBUG
Or add to application.properties:
logging.level.org.springframework.security=DEBUG
Or add to your WebSecurityConfig annotation EnableWebSecurity with debug = true:
#Configuration
#EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// ...
}

Set the log level of org.springframework.security to debug. On invoking the method with annotations, you can find log messages that indicate interceptor being applied, especially look for:
DEBUG MethodSecurityInterceptor
Updated:
That means there is some config difference between your sample app and main app
Some pointers to look for:
the <global-method-security> tag needs to be in the same context as your Spring MVC configuration otherwise your controllers will not be post processed. Refer:
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-method-security-in-web-context
you might need pre-post-annotations="enabled", with expressionHandler set.
make sure tag <global-method-security> is in application context

In case you just want to know, which method failed, simply set the logging level for this exception filter:
logging.level.org.springframework.security.web.access.ExceptionTranslationFilter: TRACE
It will only show the stack trace with the failed method and not spam your logs more than necessary ;-)

Related

Configuring spring-oauth2-client for non boot spring framework

In spring boot, application.yml takes in the Spring oauth2 client config. How do I configure it for the non-boot application. By configuration I mean giving client ID, secret, scopes and redirect URI.
You could find an example here:
https://www.baeldung.com/spring-security-5-oauth2-login#non-boot
You need to:
Build your ClientRegistration.
A ClientRegistrationRepository.
Register your repository on WebSecurityConfigurerAdapter.
If you don't use SpringBoot : there is no application.yml and even if you can add the support of yml files. It won't handle your oauth2 client config.
Anyway you can use Spring security to implement your custom Authorization Service, a User service and implement a Token Store of your choice (JBDCTokenStore or JWTTokenStore for example). But It's a very wide question depending on your business logic.
You can find some well documented samples on :
https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2
Of course you can handle both XML and javaConfig even mixed Spring confugurations.
Create a #Configuration class with a #ComponentScan on the packages containing components or bean definitions.
#Configuration
#ComponentScan({ "com.firm.product.config.xml","com.firm.product.config.java" })
public class SpringConfig {
}
You can also set properties with #PropertySource() ans #Value annotations. It's very well documented.

JerseyConfig and #Profile to hide a REST endpoint

I'm trying to hide a REST endpoint based on runtime configuration in Spring and Jersey. The most straightforward way is to throw the NotFoundException from the controller itself but maybe there's more kosher. The controller is registered in the constructor of the config class which extends org.glassfish.jersey.server.ResourceConfig.
I thought of using the #Profile annotation on the controller but I can still access the endpoint. When I hit that endpoint, I get the following error:
o.g.j.s.s.SpringComponentProvider - None or multiple beans found in Spring context
but then Jersey manages to access that controller, which I confirmed by attaching a debugger to the Spring process. So Jersey does not honor the #Profile setting.
On a separate note, I also have Swagger plugged into Jersey and when accessing the definition endpoint (.../swagger.json) I can see the endpoint provided by the #Profile-disabled controller.
Is there anything better I can do here is is throwing the NotFoundException the best option?
Note: Sorry, I thought I saw that you were using Spring Boot. The following answer is only relevant for Spring Boot.
#Profile is only good for Spring bean registration, but you are still registering the service with Jersey as a resource. What you can do is use a ResourceConfigCustomizer and add the #Profile to the customizer. This way it will only register the resource with Jersey ResourceConfig if the correct profile is active.
#Component
#Profile("..")
public class MyResourceConfigCustomizer implements ResourceConfigCustomizer {
#Override
public void customize(ResourceConfig config) {
config.register(MyResource.class);
}
}

Is there an annotation equivalent to the Spring AOP aop:include configuration for autoproxies

When specifying the XML configuration below:
<aop:aspectj-autoproxy>
<aop:include name="myBean" />
</aop:aspectj-autoproxy>
We all know that the #EnableAspectJAutoProxy annotation is the equivalent to the aspectj-autoproxy XML configuration but is there a java-based annotation equivalent for the aop:include XML configuration? I searched extensively and could not find.
Normally you tell Spring that you are using a particular feature, like Transaction management and it will create the proxies needed.
For instance #EnableTransactionManagement will cause Spring to create proxies for Components (services, controllers and repositories) which use #Transactional, you don't need to declare this, Spring automatically finds the beans that need to be proxied.
It works the same way with #EnableScheduling causing Spring to detect #Scheduled methods, and #EnableCaching to detect #Cached method.

How do I add custom interceptors to my annotation scanned spring-ws endpoint

I am using Spring-ws 2.1.4.RELEASE and Spring 3.2.8.RELEASE.
I am trying to add an interceptor to my endpoint but so far no luck even though I think my setup is very basic.
In my Spring-ws XML I have:
<sws:interceptors>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
</sws:interceptors>
<sws:annotation-driven/>
<context:component-scan base-package="package.with.my.endpoints" />
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
</bean>
In my Endpoint annotated bean I use the Spring-ws #Action annotation for ws addressing mapping:
#Endpoint("MedicineCardIdwsEndpoint")
public class MedicineCardIdws {
#Action("http://someuriandversion#GetMedicineCardIdws")
#ResponsePayload
public String getMedicineCard(#RequestPayload Element payload, SoapMessage soapMessage) {
return "";
}
However nothing is logged by the interceptor when I send a request for my endpoint. At first I thought I had configured log4j wrongly. However, if I create a breakpoint in the first line of org.springframework.ws.server.endpoint.AbstractLoggingInterceptor#handleRequest the breakpoint is never triggered.
Then I put a breakpoint inside org.springframework.ws.soap.server.SoapMessageDispatcher#headerUnderstood I can see that the only interceptor that is registered for my Endpoint is the org.springframework.ws.soap.addressing.server.AddressingEndpointInterceptor which got added because of the Action annotation.
I thought that any global interceptors in the XML configuration would end up being added to the interceptor chain for all endpoints? However it seems this is not the case. It is not just the logging interceptor, even custom interceptors are not added. So I must be doing something wrong.
I am fairly new at using Spring-ws - did I miss something in my config, or is there an annotation I need to add in order to add interceptors for annotation scanned endpoints?
Is there another way I can add interceptors to my interceptor chain when using component scanning and annotations for Spring-ws or do I need to configure all of it in XML in order to be certain that my interceptors are added to my endpoints?
I found that if I use #SoapAction annotation instead of the WS-Addressing #Action (bot from Spring-ws packages) my custom interceptors from the XML config will get added to the endpoint.
I also found this thread in the Spring forums suggesting a workaround if #SoapAction is not an option: http://forum.spring.io/forum/spring-projects/web-services/100060-interceptors-not-working-for-ws-addressing-endpoint-action

Grails Spring Security #Secured not working

I have been able to implement the #Secured annotation in one controller of my application. Yet, #Secured('ROLE_ADMIN') will NOT work anywhere else within the project.
It will only specifically work anywhere within my program controller and no where else.
For example, if I use it as so;
#Secured('ROLE_ADMIN')
The IDE gives me;
Multiple markers at this line
- Groovy:class Secured is not an annotation in #Secured
- Groovy:unable to resolve class Secured , unable to find class for
I have even tried checking the Spring Security Config file to check if annotations were set correctly (which seemingly they were).
Any ideas? Please help.
Thanks.
You are probably missing the required import.
At the top of each controller where you need the annotations use the grails import for Secured. Then you can use the annotations for the class or method as needed.
import grails.plugin.springsecurity.annotation.Secured
//import grails.plugins.springsecurity.Secured; - this is in older version,
// grails 2.0 and older
#Secured(['ROLE_ADMIN', 'ROLE_USER', 'ROLE_SUPERVISOR'])
class myClass {
}
Hope this helps.
Try this:
#PreAuthorize("hasRole('ROLE_ADMIN')" )
And add annotation support in spring configuration:
<!-- Allow configuration annotation (#Annotation-based configuration)-->
<context:annotation-config />
<!-- Enable scan classes -->
<context:component-scan base-package="com.your.package" />

Resources