Security access audit - spring

I have the following spring security configuration:
<security:http>
......
<security:intercept-url pattern="/auth/**" access="ROLE_ADMIN"/>
.........
</security:http>
I would like to log every case when "ROLE_ADMIN" user hits any of "/auth/**" URL pattern.
Can I put some kind of interceptor on this pattern?

I had to do the same thing. Use an #Aspect which fires for every execution of a handler method in your /auth/ controller. Annotate the class as a #Component so its a Spring bean, add the AspectJ #Aspect annotation, and you can then inspect the JoinPoint for whatever the user is doing - method signature, objects, etc. Write whatever you find to an audit table.
See http://static.springsource.org/spring/docs/current/reference/aop.html for full details. I would think a #Before or #After would work for your purposes.

Related

How to debug Spring Security authorization annotations?

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 ;-)

Locking on spring mvc session command object

I hava a spring 4 mvc controller. I am using annotations to handle multiple requests in the same controller. - e.g.
#RequestMapping("/add_dob")
public String addDateOfBirth(.......) {
........
validateDOB(form, result)
........
}
#RequestMapping("/add_address")
public String addAddress(.......) {
........
}
The thing is that I have a session command object (PERSON) and there is a possibility of the command object becoming inconsistent. I tried using
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="synchronizeOnSession" value="true" />
</bean>
in the servlet-name.xml spring file but this is causing all requests on the application to be synchronized (I tested by putting Thread.sleep inside the request on which I intend to synchronize and then tried to access the home page). Is there any way by which I can just synchronize on the session command object or on a scope smaller than the entire session?
Thanks
You could use a specific session-scoped bean, e.g. Person:
<bean class="com.xyz.Person" scope="session">
<aop:scoped-proxy/>
</bean>
Or with annotations:
#Bean #Scope("session") #ScopedProxy class Person {...}
You can then #Autowire this bean to your web service class. Spring guarantees that any time you reference it you will receive the object from the current session. See here for more details.

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

Spring AOP logging for HTTP request

I am trying to log the http request in controller by aop. However, in the aspect code, if I
httpServletRequest.getInputStream()
then the request data will not be able to retrieve in main flow.
So, I created another public method with in the controller which pass in the request string
public String processRequest(String data){...}
and this method is a pointcut for logging the "data".
But the problem is, seems the point cut for this method is not be able to identify by Spring, there is no logging for this method. I need help on this.
Here is the define for the aop
<bean id="myLogger" class="com.my.MyLogger" />
<aop:config>
<aop:aspect id="Log" ref="myLogger">
<aop:around method="log" pointcut="execution(public * com.my.controller.processRequest(..))" />
</aop:aspect>
</aop:config>
Spring AOP by default uses AOP proxies. So your original bean is wrapped with generated proxy bean and all "outside" calls go through the proxy. Internal method calls (within the same bean) bypass proxy.
It's nicely explained here: http://static.springsource.org/spring/docs/2.5.5/reference/aop.html#aop-understanding-aop-proxies

Secured annotations in spring security

I am trying to configure security annotations in spring security. But I have a question about this -
....
<security:http auto-config="true" use-expressions="true">
....
and when I use
#Secured("CUSTOM_ACCESS")
public String query();
it doesn't work. But I use
#PreAuthorize("hasRole('CUSTOM_ACCESS')")
public String query();
it works correctly and applies relevant Role. Does this mean #Secured annotations doesn't work with #PreAuthorize?
I also tried adding
<security:global-method-security secured-annotations="enabled" />
But it doesn't help.
<security:global-method-security pre-post-annotations="enabled" />
The above config works fine. Any ideas?
First off, the use-expressions setting in your <http> element has no effect on method security annotations. Those are enabled using global-method-security.
Using
<security:global-method-security pre-post-annotations="enabled" />
will enable PreAuthorize and its related annotations. The reason the secured annotation isn't working when you enable that is because there is no voter which knows what CUSTOM_ACCESS means. In its default setup Spring Security's RoleVoter only consumes attributes which start with the prefix ROLE_. See this FAQ for more information.
Voters can be used for things other than checking for simple roles, so they typically need some way of determining which of the attributes configured for a method apply to them. The expression-based annotations operate differently from the standard voters. The hasRole expression just looks for a named authority which is assigned to the user.
So if you created an AccessDecisionManager for method security, with an AccessDecisionVoter which consumes your CUSTOM_ACCESS attribute then the #Secured annotation would have an effect. However since you have it working with PostAuthorize already you may just want to stick with that.

Resources