SPEL expressions not evaluated dynamically - spring-security

I am trying to filter URLs using spring security. Following is a definition for filtering:
<intercept-url pattern="/page" access="#{new java.io.File('file_path').exists()}"/>
The URL is restricted based on existence of a file called file_path.
If the file_path exists at the time the spring configuration file is loaded, the access is provided. If the file_path is created after load, access is not provided. I would like the expression to be evaluated every time the request to /page is made & not just during compilation of the expression.
Tried to set the system property -Dspring.expression.compiler.mode=MIXED but there is no effect.
Can anybody please help me in this?

That's correct because you use the configuration time expression (#{...}). To achieve the requirements you should use something like this:
<http use-expressions="true">
<intercept-url pattern="/admin*"
access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/>
</http>
See Expression-Based Access Control. So, in your case it can be like this:
<http use-expressions="true">
<intercept-url pattern="/page" access="new java.io.File('file_path').exists()"/>
</http>

Related

Path based vulnerability in Spring hybris

We have got path based vulnerability issues in Qualys report. I have gone through stackoverflow questions like this one and configured useDefaultSuffixPattern as false as shown below.
I am still able to load the page with /about.anything even though in controller I have given as #RequestMapping(value = "/about")
Is there any other configuration we need to update to stop this from happening?
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="0" />
<!-- Set whether to register paths using the default suffix pattern as
well: i.e. whether "/users" should be registered as "/users.*" and "/users/"
too. Default is "true". Turn this convention off if you intend to interpret
your #RequestMapping paths strictly. Note that paths which include a ".xxx"
suffix or end with "/" already will not be transformed using the default
suffix pattern in any case. -->
<property name="useDefaultSuffixPattern" value="false" />
<property name="pathMatcher" ref="pathMatcher" />
</bean>
We are using hybris 1811 version
This might be happening because of an inherent bug in Spring where it ignores everything after the dot(.) in the URL.
To resolve this you must create the path variable pattern for GET call in your controller more rigid.

Spring Security <http> and <intercept-url> pattern attributes

I have seen Spring Security OAuth2 samples has this defined in the spring-servlet.xml,
<http pattern="/users/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/photos" access="ROLE_USER,SCOPE_READ" />
<intercept-url pattern="/photos/trusted/**" access="ROLE_CLIENT,SCOPE_TRUST" />
<intercept-url pattern="/photos/user/**" access="ROLE_USER,SCOPE_TRUST" />
<intercept-url pattern="/photos/**" access="ROLE_USER,SCOPE_READ" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
Is the pattern attribute in http tag valid? I could not find its definition in the spring-security-2.0.1.xsd. If it is valid, what is the relationship of this pattern with intercept-url's pattern attribute? Take for example, does the intercept path /photos/user/** has the final matching interception path of /users/photos/user/**? Thanks.
The pattern attribute was introduced in 3.1 which introduced namespace support for multiple filter chains. Spring Security 2 is very out of date (you shouldn't be using it).
The patterns in the intercept-url elements are independent, in that they are matched against the incoming request URI in the same way as the filter chain http pattern is checked. However if the latter doesn't match, the filter chain won't be applied to the request at all, so in order to have any effect, they must be consistent with the filter chain pattern.
For the example you've posted, this would mean that none of the /photos patterns have any effect. They should all have the prefix that the main filter chain matches - i.e. they should begin with /users/photos.
In the case of spring security 4, Role is checked by haseRole('ADMIN'), Just try it.
It works fine for me.

Spring security: share intercept-url between configuration

I have two different configuration of spring security, one for local development and the other per test and production server. They are quite different but need to share the "intercept-url" part.
Consither this:
<security:http ... >
<security:http-basic />
<security:anonymous />
<security:intercept-url ... />
<security:intercept-url ... />
...
</security:http>
I need to share the list of the intercept-url tags between two different http tags.
Is there a way to do this?
That's not something you can easily do with the namespace.
If you are just defining access constraints, one possibility might be to define an external filter-security-metadata-source and write a BeanPostProcessor to inject it into the FilterSecurityInterceptor.
However, it's probably not worth the trouble for something like this.
Another option would be to externalize the authentication filters you want to use as beans (use the custom-filter element to add them to the <http> configuration) and configure them separately depending on your environment. It would be easier to suggest how feasible that is if you could post both configurations explicitly to see how much overlap there is.

Spring roo security setup with CUD but not R?

I am trying to to setup a security policy in Spring such that anyone can read any entities created in roo but only the admin user (specified in the applicationContext-security.xml) can create/update/delete. It seems to me I should be able to achieve my goal by customizing applicationContext-security.xml but I can't figure out a way. I thought of using intercept-url like:
<intercept-url pattern="/anyEntity/*?form" access="hasRole('ROLE_ADMIN')" />
but this config does not cover DELETE because it is a hidden field in POST (according to the doc, post method is supported but there is no doc on how to specify a hidden field value in the intercept-url tag)
Another way would be to use #secured on entity setter methods. I currently rely on roo to generate the getters/setters so I would like to avoid using it if possible
I can also write a custom controller to do the filtering I suppose. But seems to me I should be able to just customize the configuration. I must be missing something obvious because a public read-only policy should be a very common strategy.
I think you can use the method="DELETE" attribute to intercept-url because roo converts the hidden method field to the http method.
There is also some more information here
Here is how I did it:
<!-- only user role can use modify methods -->
<intercept-url pattern="/**" method="POST" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" method="DELETE" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" method="PUT" access="hasRole('ROLE_USER')" />
<!-- any role can use GET methods -->
<intercept-url pattern="/**" method="GET" access="isAuthenticated()" />
<intercept-url pattern="/**" method="HEAD" access="isAuthenticated()" />
<intercept-url pattern="/**" method="OPTIONS" access="isAuthenticated()" />
<intercept-url pattern="/**" method="TRACE" access="isAuthenticated()" />

how to change default-target-url depending on user role

I use spring security for user authentication. In security.xml I have
<form-login login-page="/login"
default-target-url="/dashboard"
always-use-default-target="false"
authentication-failure-url="/login/error"
login-processing-url="/j_security_check"/>
I want to be able to configure different target urls for different user roles. How do i do this?
Thanks!
If you're using Spring-Security 3.0 or higher implementing your own AuthenticationSuccessHandler is the way to go:
<sec:form-login ... authentication-success-handler-ref="successHandler"/>
...
<bean id="successHandler" class="de.....MySpecialAuthenticationSuccessHandler">
Then MySpecialAuthenticationSuccessHandler can extend one of the default handlers like SavedRequestAwareAuthenticationSuccessHandler though they are not really inheritance-friendly.
see -
http://forum.springsource.org/showthread.php?t=93541
I don't think you can configure this, but your default-target-url dashboard can contain logic to redirect to appropriate page based on the role.

Resources