Authorization Before Accessing Static Resources In Spring Web App - spring

I have mapped the static resources in my application in spring's configuration xml like this
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
Now i want that only users who have authentication and authorization can only access images in that folder as far as authentication is concerned i 've achieved that through spring security like this
<sec:intercept-url pattern="/resources/**" access="isAuthenticated()" />
but i dont want authenticated user to access all of the images in that folder he can access only a subset of images stored in that folder based on certain boundations so what i want that for every request to the image done by the user i want to perform security check whether he is permitted to visit that particular image How To Do that ???

The simplest solution is to move all non-secured images into a separate folder and to make the folder not secured:
<!-- This line BEFORE resources/** pattern -->
<sec:intercept-url pattern="/resources/nonsecuredimages/**" access="permitAll"/>
<sec:intercept-url pattern="/resources/**" access="isAuthenticated()" />

Related

SpringSecurity do not forward to https

Dear All,
We have added Spring Security for our web application. Login url seems like this
https://www.xyz.com/app/login.do
after login it should redirect to other urls with same https protocol. Right now SpringSecurity redirect us to other urls but with http not https.
Please tell us any specific settings are needed.
Thanks,
Op
Within your spring security definitions, inside your intercept-url tag you need to add requires-channel="https"
For example:
<sec:intercept-url pattern="/login.jsp*" requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/j_spring_security_check*" requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<sec:intercept-url pattern="/**" requires-channel="https" access="IS_AUTHENTICATED_FULLY"/>

Spring+ LDAP integration

I want to integrate LDAP in my spring application.
Requirement:- On request it should divert to my login page then ask for user/password. Then on submit it should authentication from LDAP.
Thanks
There is a special project in Spring called Spring Security for this purpose. The core functionality is built as a set of servlet API filters. There are multiple connectors for user's database (LDAP, DB, Active Directory, etc.) Here you can see how to add a basic conf. Your conf may looks like this:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login />
<logout />
</http>
Note that I prefer SpEL expressions for security rules. And here you can see how to add LDAP.
Hope it helps.
Along with that you also need other LDAP configuration like this
<ldap-server url="ldap://localhost:10389/dc=example,dc=com" />
<authentication-manager alias="authenticationManager"
erase-credentials="true">
<ldap-authentication-provider
user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups"
group-search-filter="(members={0})">
</ldap-authentication-provider>
</authentication-manager>

AngularJS and Spring Security. How to handle AngularJS Urls with Spring Security

Let me explain my problem.
I have implemented a site in AngularJS that is accessed like this:
http://localhost:8080/example/resources/#/
Here we can call different pages, for example a Login page:
http://localhost:8080/example/resources/#/login
admin page:
http://localhost:8080/example/resources/#/admin
user page:
http://localhost:8080/example/resources/#/user
Now, I have implemented spring security in the example in order to catch every call and check if it has ROLE_USER privileges. So far so good, I have done it like this configuration in Spring security context file:
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>
This configuration checks for every url called, if the user has the proper ROLES, and it works fine, throws 401 Unauthorized page.
The problem I`m having is that when I put the login page to be accessed by everybody I'll do it this way:
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
<security:intercept-url pattern="/login**" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>
But I dont know why spring security is not catching this URL. Maybe Angular manages the URL differently.
Finally i have tried deleting the <security:intercept-url pattern="/**" access="ROLE_USER" /> and giving /login** access to ROLE_USER only, but this page was not found. Does anybody know what could be happening here?
Thanks in advance!!!
I wrote a little sample application that illustrates how to integrate AngularJS with Spring Security by exposing the session id as an HTTP header (x-auth-token). The sample also provides some (simple) authorization (returning the roles from the server) so that the client AngularJS application can react to that. This is of course primarily for user-experience (UX) purposes. Always make sure your REST endpoints have property security.
My blog post on this is here.

Why is my Spring PreAuthFilter always called?

I have my Spring 3.1 app configured like this
<http use-expressions="true" entry-point-ref="http401UnauthorizedEntryPoint">
<intercept-url pattern="/app/demo" access="hasRole('Demo')" />
<intercept-url pattern="/app/**" access="isAuthenticated()" />
<intercept-url pattern="/admin/**" access="hasRole('Admin')" />
<custom-filter position="PRE_AUTH_FILTER"
ref="currentWindowsIdentityAuthenticationFilter" />
<logout invalidate-session="true" delete-cookies="JSESSIONID"
logout-url="/logout" logout-success-url="/logout-success" />
</http>
I have written a custom preauth filter. When I call my app at the root URL / the filter chain hooks in and runs the preauth filter although this resouce is not protected. This means that the logout does not work as designed. After a logout a login is performed again.
My implementation is based on the org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter class.
Is this normal behavior or can this be fixed some how? I'd like the auth be performed on the protected URLs only.
As I side note, I do not intend to configure security='none' because I want to maintain the security context on all pages.
I have posted the appropriate log out on pastebin. It is too verbose to include in here.
Seems that what you want is creating special <http> without any filters for logout URL:
<http pattern="/logout/**" security="none" />
<http use-expressions="true" entry-point-ref="http401UnauthorizedEntryPoint">
<intercept-url pattern="/app/demo" access="hasRole('Demo')" />
<intercept-url pattern="/app/**" access="isAuthenticated()" />
<intercept-url pattern="/admin/**" access="hasRole('Admin')" />
<custom-filter position="PRE_AUTH_FILTER"
ref="currentWindowsIdentityAuthenticationFilter" />
<logout invalidate-session="true" delete-cookies="JSESSIONID"
logout-url="/logout" logout-success-url="/logout-success" />
</http>
Read more about request matching mechanism here.
EDIT:
#LukeTaylor mentioned that if you want to create another filter chain then the pattern should go in the element (is this documented somewhere explicitely?), so my idea with separate chain without PRE_AUTH_FILTER obviously won't work. Added <http> for /logout without any filters, which should prevent authorizing at logout requestes.
Still, I don't know how prevent requests like /other from applying PRE_AUTH_FILTER. One way could probably be abandon <http> namespace configuration to manual filterChainProxy configuration with two <sec:filter-chain> patterns, but I don't know if it's worth it.
#Michael-O: About exception IllegalArgumentException: A universal match pattern ('/**') is defined before other patterns - it's strange, is it your whole XML config for Security? Or maybe it's just a consequence of what Luke said (that another <http> element should have pattern)...
I was able to indentify the issue but it cannot be solved the way it is now because of the way the entire chain works.
Here's the deal:
When you define a <http> element on /** you ask Spring Security to fire the entire filter chain on all paths under your defined pattern. It does not matter whether one of them needs protection or not. Rob Winch published a very helpful video. If you take a closer look at the default filter stack you'll what filters are applied. Amidst these is my filter located.
The first ten lines of my log file reveal that the entire chain is fired since / matches the <http> configuration. At the end, the FilterSecurityInterceptor sees that this resource does not need protection. More over, you see that the CurrentWindowsIdentityAuthenticationFilter is fired too and performs unwanted authentication.
Why? Compared to header-based filters or URL processing filters you have no trigger/entry point to commence the authentication deliberately you simply do without challenging the client regardless the URL needs protection or not. Defining something like this <http pattern="/unprotected-url" security="none" /> saves you absolutely nothing because you lose the security context on unprotected paths. You want to keep your client logged in regardless of the URL protection.
How can this be solved now? You have two options:
Define a <http> element on /app/**, /admin/** so on but this is really cumbersome and contains repitions all over. I would not recommend such a solution. Additionally, you probably won't have the sec context on other URLs in /**. This is not desired.
Split the preauth filter in two filters:
CurrentWindowsIdentityPreAuthenticationFilter
CurrentWindowsIdentityUrlAuthenticationFilter
The second option solves the problem.
CurrentWindowsIdentityPreAuthenticationFilter: Remains as-is and peforms the auth always. Very helpful for M2M communication like script access or REST requests.
CurrentWindowsIdentityUrlAuthenticationFilter: Suits human interaction very well. It works basically like a form-based filter. If define a URL, say /login, you will get redirected to when you request a protected resource and after successful auto-auth you be redirected back to your actual resource. Auth is done. Public resources remain unauthenticated because the preauth filter is trigged on /login only just like form-based. If you log out you stay logged out.
I'd be happy if any of the Spring folks can confirm my analysis.

Spring Security 3.1 intercept urls

I have my configuration of intercept url like
<security:http use-expressions="true" disable-url-rewriting="true">
<security:intercept-url pattern="/secure/admission/*" access="hasRole('ROLE_ADMISSIONER')" />
<security:intercept-url pattern="/secure/subdean/*" access="hasRole('ROLE_SUBDEAN')" />
<security:intercept-url pattern="/secure/referent/*" access="hasRole('ROLE_REFERENT')" />
<security:intercept-url pattern="/secure/index.xhtml" access="hasRole('ROLE_REFERENT, ROLE_SUBDEAN')" />
<security:intercept-url pattern="/secure/*" access="hasRole('ROLE_OMNI_ADMIN')" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
But now I have a problem that it is possible to acces url of my application, for example MY_APPLICATION/PririzMaven/secure/admin/updateRole.xhtml with role ROLE_ADMISSIONER, url ..../secure/subdean/* with this same role and so on... but it should by banned to this user.
Do you know where could be a problemme?
Assuming PririzMaven is the context path of your application, /secure/admin/updateRole.xhtml will be matched by the path /** and hence will be accessible to all authenticated users. You have no rule for /secure/admin. Note also that a single '*' does not match subpaths. For example, you should use /secure/admin/** to match everything under this path.
You should also enable debug logging and check how the rules are being applied - you should see the matchers being called against the incoming request URL and will see what is being compared and what is being matched against.
Finally, it's worth adding <security:debug /> at the top of your application context file, which will add other useful debugging information on request handling in a more human-readable format.

Resources