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?
Related
Code was working fine now have replaced the below line in security.xml to provide role based security, but getting access denied http status-403
Replaced
<intercept-url pattern="/inputcreate*" access="isAuthenticated()" />
with
<intercept-url pattern="/inputcreate*" access="hasAnyRole('admin','user')" />
spring-security.xml
<http use-expressions="true" auto-config="true">
<!-- <intercept-url pattern="/inputcreate*" access="isAuthenticated()" /> -->
<intercept-url pattern="/inputcreate*" access="hasAnyRole('admin','user')" />
<form-login login-page="/login.html" default-target-url="/inputcreate.html"
authentication-failure-url="/login.html" username-parameter="j_username"
password-parameter="j_password" login-processing-url="/j_spring_security_check" />
<logout logout-url="/j_spring_security_logout"
logout-success-url="/index.html" />
</http>
just Replaced
<intercept-url pattern="/inputcreate*" access="hasAnyRole('admin','user')" />
with
<intercept-url pattern="/inputcreate*" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />
After googling 3-4 hour, made this above change
This worked for me!!!!
In the Spring documentation it has been given here, to prefix role
public void setRolePrefix(String rolePrefix)
Allows a default role prefix to be specified. If this is set to a non-empty value, then it is automatically prepended to any roles read in from the db.
This may for example be used to add the ROLE_ prefix expected to exist in role names (by default) by some other Spring Security classes, in the case that the prefix is not already present in the db.
Parameters:
rolePrefix - the new prefix
I created a spring mvc application with spring security. I tried to set authentication for all url with spring security.
Springsecurity.xml
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService" >
<password-encoder hash="bcrypt" />
</authentication-provider>
</authentication-manager>
When I giving intercept-url to /** the page doesnot loading. It makes a timeout.
But when giving intercept-url to /admin it works perfectly. Why this happens?
Your intercept pattern for all request is OK, but you need to include an exception for your login page, try adding
<http security="none" pattern="/login"/>
UPDATE with respect to the comment
The approach above completely switches off Spring security for the given URL. As you're using CSFR, it means that spring security filter should attend to this URL as well, but not for the sake of the authentication, rather for the sake of including the unpredictable token that can secure from session fixation attacks. In any case, here's a way to process the URL with spring security, without prompting for authentication. Instead of using the above, use the following
<intercept-url pattern="/login" access="isAnonymous()"/>
inside the
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="isAnonymous()"/>
<intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')" />
...
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.
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>
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')" />