I have a java + spring web application and spring security 3.0 is applied to it.
Using the security intercept url I'm trying to apply none filter to a particular view (jobs.jsp) however when I request for that url the request mapping works, but returning the view (ModelAndView as jobs.jsp) does not work.
It gives me an error saying that could not found /WEB-INF/view/jobs.jsp , however the file is right there.
I think the spring security does not allow this resource to be accessed unless authenticated?
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="hasRole('admin')" />
<security:intercept-url pattern="/resources/static/login.html" filters="none"/>
<security:intercept-url pattern="/resources/static/home.html" filters="none"/>
<security:intercept-url pattern="/home/*" filters="none"/>
<security:intercept-url pattern="/job/all/*" filters="none"/>
<security:intercept-url pattern="/resources/css/*" filters="none"/>
<security:intercept-url pattern="/resources/js/*" filters="none"/>
<security:intercept-url pattern="/resources/images/*" filters="none"/>
<security:form-login login-page ="/resources/static/login.html"
authentication-failure-url="/resources/static/login.html"/>
<security:logout logout-url="/logout"
logout-success-url="/resources/static/home.html"/>
The order of intercept url's caused the problem. This one works.
<security:intercept-url pattern="/job/all/*" access="isAnonymous()"/>
<security:intercept-url pattern="/**" access="hasRole('admin')" />
Related
I am using Spring Security in my project.
In the XML for configuring the security, I want to use 'Spring EL'. Instead of using access="ROLE_ADMIN" I want to use hasRole('ROLE_ADMIN') and isAuthenticated() for the access values mentioned in below code.
For that I used 'use-expressions="true"' in <http> tag. But I am still not getting output. It says that the resource is not available.
The code is currently working properly but I want to use Spring EL.
XML file:
<!-- security configuration -->
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/admin" access="ROLE_ADMIN" />
<security:intercept-url pattern="/welcome" access="ROLE_ADMIN" />
<security:access-denied-handler error-page="/accessdenied403" />
<security:form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<security:logout logout-success-url="/login?logout" />
</security:http>
So, how to use Spring EL to set value for access?
does your updated config now looks like
<security:intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/welcome" access="hasRole('ROLE_ADMIN')" />
Which version of Spring and Spring Security you are using?
What exception you are getting can you set log level to trace and post the log along with any stack trace here?
Are you sure you have all required jar in class path?
I am currently exploring the possibility of having two separate log in page for different users.
I am now able to to set most urls according to the two pages. However, i am now having a configuration issue for the entry-point-ref and CONCURRENT_SESSION_FILTER.
As for this security version, ( LoginUrlAuthenticationEntryPoint.class - loginFormUrl ConcurrentSessionFilter.class - expiredUrl ) the setter method for the property are deprecated, left with the constructor injection that is set in the xml.
So I am thinking of two ways to solve this problem:
1. Override or Inject the two classes and change the url base on condition ?
2. Write a seperate http tag that reads in the specific url pattern and apply the configurations accordingly.
Thanks in advance. The working code is below:
<security:global-method-security pre-post-annotations="enabled" />
<security:http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:intercept-url pattern="/*" requires-channel="any"/>
<security:intercept-url pattern="/**/*.json*" requires-channel="any"/>
<security:intercept-url pattern="/**/dashboard/**" requires-channel="https"/>
<security:intercept-url pattern="/**/rest/**" requires-channel="https"/>
<security:intercept-url pattern="/**/cart/**" requires-channel="https"/>
<security:intercept-url pattern="/**/customer/**" requires-channel="any"/>
<security:intercept-url pattern="/**/api/**" requires-channel="any"/>
<security:intercept-url pattern="/api/**" access="permitAll"/>
<security:intercept-url pattern="/dashboard/signin" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/dashboard/signup" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/rest/signin" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/rest/signup" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/denied" access="permitAll"/>
<security:access-denied-handler error-page="/denied"/>
<security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<security:custom-filter before="FORM_LOGIN_FILTER" ref="customDeveloperPasswordAutenticationFilter"/>
<security:custom-filter after="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
<security:logout logout-url="/j_spring_security_logout" success-handler-ref="customLogoutSuccessHandler"/>
</security:http>
The code i'm trying to achieve is:
<security:global-method-security pre-post-annotations="enabled" />
<security:http auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:intercept-url pattern="/*" requires-channel="any"/>
<security:intercept-url pattern="/**/*.json*" requires-channel="any"/>
<security:intercept-url pattern="/**/dashboard/**" requires-channel="https"/>
<security:intercept-url pattern="/**/cart/**" requires-channel="https"/>
<security:intercept-url pattern="/**/customer/**" requires-channel="any"/>
<security:intercept-url pattern="/**/api/**" requires-channel="any"/>
<security:intercept-url pattern="/api/**" access="permitAll"/>
<security:intercept-url pattern="/dashboard/signin" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/dashboard/signup" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/denied" access="permitAll"/>
<security:access-denied-handler error-page="/denied"/>
<security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<security:custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
<security:logout logout-url="/j_spring_security_logout_user" success-handler-ref="customLogoutSuccessHandlerUser"/>
</security:http>
<security:http auto-config="false" use-expressions="true" entry-point-ref="restUrlAuthenticationEntryPoint">
<security:intercept-url pattern="/**/rest/**" requires-channel="https"/>
<security:intercept-url pattern="/rest/signin" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/rest/signup" requires-channel="https" access="permitAll"/>
<security:intercept-url pattern="/denied" access="permitAll"/>
<security:access-denied-handler error-page="/denied"/>
<security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="restConcurrencyFilter" />
<security:custom-filter position="FORM_LOGIN_FILTER" ref="customDeveloperPasswordAutenticationFilter"/>
<security:logout logout-url="/j_spring_security_logout_developer" success-handler-ref="customLogoutSuccessHandlerDeveloper"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="customPasswordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<bean id='customUserDetailsService' class='sg.oddlefnb.common.security.CustomUserDetailServiceImpl'>
<!-- use to DAO to switch for different condition -->
<property name='userDao' ref='userDao' />
<property name='developerDao' ref='developerDao' />
</bean>
However, this could not run.. Any advice?
You should not try to do it that way, it is not the spring security way. Maybe you could succeed (even if I doubt you can ...) but it will be hard to write and to maintain.
You can have multiple <http> blocs in a single config, but it is when you want to apply different filter chains to different URL blocs.
You may have different login pages (and also different authentication methods : login page, basic authentication, ldap, custom ...). But the spring way is to separate authentication and access control. So when a user is authenticated, his authentication is stored in session and will be used for all following requests (until end of session). In your example if someone asks for a user page before authentication, if will be redirected to user login page, authenticated as a user and he will get its page. But if he asks for a developper page on next request, spring security will find a valid authentication in session a permitAll as access rule and will allow the page ... which I assume is not what you want !
The spring security way to do what you want is to use roles. The simple way is to have one single page, and store the roles in a database (or in a in-memory store for developpement and tests). You the use the roles in the access rules. You will find many examples for that in Spring Security Reference Manual.
Edit per OP comment :
It is rather uncommon to assign roles depending on used login page, but it can be done. You simply need to define two different AuthenticationManager beans, and explicitely assign them to the two different <http> blocs where you declare your login pages. In one you explicitely affect a ROLE_USER granted authority, and in the other a ROLE_DEVELOPPER one. You may do it by hand by subclassing a ProviderManager and using same AuthenticationProviderS in both, or you can use plain ProviderManager and customize the UserDetailsService beans of the AuthenticationProviderS. If you showed your current <authentication-manager> bloc, I could easily propose a full solution.
Once you have different roles, it is easy to put all access control in one single <http> bloc, with all the <security:intercept-url .../> inside it.
How can I configure, so that the GET version of an URL is bypassed by the custom filters, but not the POST version of that URL. I tries using "filters=none" in , but its not working. My configuration is like:
<http auto-config='true' use-expressions="true" create-session="never" >
<custom-filter position="FIRST" ref="authenticationFilter" />
<intercept-url pattern="/v0_2/app" method="GET" access="permitALL" filters="none"/> // Its not working
<intercept-url pattern="/v0_2/app" method="POST" access="permitALL" />
<intercept-url pattern="/**" access="permitALL" />
</http>
Even with ""secuirty=none" option, there is no provision of providing the http method. It bypasses all http methods of the URL.
<http pattern="/v0_2/app" security="none" />
Please let me know, how can I do bypass the GET method only.
-Thanks
You can have something like :
<intercept-url pattern="/v0_2/app" method="GET" access="permitAll"/>
<intercept-url pattern="/v0_2/app" method="POST" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
or
<intercept-url pattern="/v0_2/app" method="GET" access="permitAll"/>
<intercept-url pattern="/v0_2/app" method="POST" access="denyAll"/>
denyAll will make every POST request to go through filter.
I am using Spring security within my web application, and I am utilising the 2 standard authorisation levels 'ROLE_USER', and 'ROLE_ADMIN'. Is there any possibility that I can add another level?
Simply add them to your intercept-url tag. For example I have the following configuration:
<security:http auto-config="false" use-expressions="true" access-denied-page="/denied.do"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/index.do" access="hasAnyRole('PROGRAM_VIEW', 'PROGRAM_ADMIN')"/>
<security:intercept-url pattern="/**" access="hasAnyRole('PROGRAM_VIEW', 'PROGRAM_ADMIN)"/>
<security:custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>
<security:logout invalidate-session="true" logout-success-url="/" logout-url="/logout.do"/>
</security:http>
My additional roles are PROGRAM_VIEW and PROGRAM_ADMIN (I'm not using ROLE_ADMIN and ROLE_USER).
These additional roles are coming from database.
I'm trying to configure spring MVC to not authenticate any pages that have no authentication (enable the use of ROLE_ANONYMOUS as explicitly required for all pages).
But I get this message in the debug logs:
o.s.s.w.a.i.FilterSecurityInterceptor - Public object - authentication not attempted
The FilterSecurityInterceptor is added by the namespace. And I think I need to setRejectPublicInvocations on the filter to disable this.
But I don't see any way to do this through the http namespace. Do I have to abandon using the http namespace entirely just to accomplish this?
In my case I basically did this.
and it's working for anon users.
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/img/**" filters="none" />
<intercept-url pattern="/loginform.*" filters="none" />
<intercept-url pattern="/topic/addtopic**"
access="hasAnyRole('USER_ROLE','ADMIN_ROLE','OPER_ROLE')" />
<intercept-url pattern="/user/**"
access="hasAnyRole('USER_ROLE','ADMIN_ROLE','OPER_ROLE')" />
<intercept-url pattern="/admin/**" access="hasRole('ADMIN_ROLE')" />
<intercept-url pattern="/cadastro.*" filters="none" />
<form-login login-page="/loginform.html"
authentication-failure-url="/loginform.html?error=invalido" />
</http>