Spring security How to define custom role name - spring

I have found some solutions but none of them worked for me. Below code gives
"Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Unsupported configuration attributes: [admin]"
error. When I change auto-config attribute to "true", again gives same error.
<http auto-config="false">
<intercept-url pattern="/pages/login.xhtml*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="admin" />
<form-login login-page='/pages/login.xhtml' default-target-url="/**"
authentication-failure-url="/pages/login.xhtml"/>
<logout logout-success-url="/pages/logout.xhtml" />
</http>
<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value=""/>
</beans:bean>

You need to provide your own decision manager (e.g. org.springframework.security.access.vote.AffirmativeBased) with your custom configured decision voters via access-decision-manager-ref="decisionMangerId" attribute.
But be aware that having no prefix in role voter is not a good idea as it will just try to interpret all security attributes as roles. I strongly recommend to use some prefix, if not the default ROLE_.
Or you can enable expression based parsing via use-expressions="true" and use access="hasRole('admin')" expresion. When going this way, you will also need to change your IS_AUTHENTICATED_ANONYMOUSLY condition with access="permitAll".

It should read:
access="hasRole('admin')"

Related

Spring Security 3.2 xml configuration in version 3.2

I am trying to update my Spring Security version from 3.0 to 3.2. Following is the current config:
<security:http auto-config="true" realm="Domaine XXX" access-denied-page="/jsps/login/access-denied.action">
<security:http-basic />
<security:intercept-url pattern="/services/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/index.jsp" filters="none" />
<security:intercept-url pattern="/jsps/i18n/**" filters="none" />
<security:intercept-url pattern="/**/Action1.action" filters="none" />
<security:intercept-url pattern="/**/Action2.action" filters="none" />
<security:intercept-url pattern="/**/Action3.action" filters="none" />
<security:intercept-url pattern="/**/Result.action" filters="none" />
<security:intercept-url pattern="/isalive.html" filters="none" />
<security:intercept-url pattern="/**/layout/**" filters="none" />
<security:intercept-url pattern="/**/acc.action" filters="none" />
<security:intercept-url pattern="/**/loadLoginCombo*" filters="none" />
<security:intercept-url pattern="/**/access-denied.action" filters="none" />
<security:intercept-url pattern="/**/logout.action" filters="none" />
<security:intercept-url pattern="/**/*.js" filters="none" />
<security:intercept-url pattern="/**/*.css" filters="none" />
<security:intercept-url pattern="/**/*.ico" filters="none" />
<security:intercept-url pattern="/**/*.gif" filters="none" />
<security:intercept-url pattern="/**/*.jpg" filters="none" />
<security:intercept-url pattern="/**/setLocale.action*" filters="none" />
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<security:logout logout-url="/logout.action" invalidate-session="true" logout-success-url="/logout.action" />
<security:form-login login-page="/index.jsp" authentication-failure-url="/access-denied.action" default-target-url="/pageBlank.action" />
<!-- security:concurrent-session-control max-sessions="5" exception-if-maximum-exceeded="true" / -->
</security:http>
When I host the application , I get the following message:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: The use of "filters='none'" is no longer supported. Please define a separate element for the pattern you want to exclude and use the attribute "security='none'".
What exact changes should I make to conform to Spring Security 3.2 standards?
Since Spring Security 3.1 filter="none" is not supported anymore, see Spring Security Reference:
[4] The use of multiple <http> elements is an important feature, allowing the namespace to simultaneously support both stateful and stateless paths within the same application, for example. The previous syntax, using the attribute filters="none" on an intercept-url element is incompatible with this change and is no longer supported in 3.1.
You have to use <http>, see Spring Security Reference:
From Spring Security 3.1 it is now possible to use multiple http elements to define separate security filter chain configurations for different request patterns. If the pattern attribute is omitted from an http element, it matches all requests. Creating an unsecured pattern is a simple example of this syntax, where the pattern is mapped to an empty filter chain [4]. We’ll look at this new syntax in more detail in the chapter on the Security Filter Chain.
and Spring Security Reference:
13.6 Advanced Namespace Configuration
As we saw earlier in the namespace chapter, it’s possible to use multiple http elements to define different security configurations for different URL patterns. Each element creates a filter chain within the internal FilterChainProxy and the URL pattern that should be mapped to it. The elements will be added in the order they are declared, so the most specific patterns must again be declared first. Here’s another example, for a similar situation to that above, where the application supports both a stateless RESTful API and also a normal web application which users log into using a form.
<!-- Stateless RESTful service using Basic authentication -->
<http pattern="/restful/**" create-session="stateless">
<intercept-url pattern='/**' access="hasRole('REMOTE')" />
<http-basic />
</http>
<!-- Empty filter chain for the login page -->
<http pattern="/login.htm*" security="none"/>
<!-- Additional filter chain for normal users, matching all other requests -->
<http>
<intercept-url pattern='/**' access="hasRole('USER')" />
<form-login login-page='/login.htm' default-target-url="/home.htm"/>
<logout />
</http>

Spring Security permitAll doesn't work

I am using Spring Security. I have a Controller in which some methods have to be possible to access by any user regardless if he is authenticated or not, some methods have to be possible to access only to users who are authenticated with a JWT token. I have configured some paterns with acces="permitAll()" but it seems not to work. If I try to access localhost:8080/name-of-the-app/services/public/whatever I get 401 which I return in my MobileJWTAuthenticationEntryPoint.commence method. Can you help me?
This is my context.xml:
<security:global-method-security pre-post-annotations="enabled"/>
<security:http entry-point-ref="mobileJWTAuthenticationEntryPoint"
authentication-manager-ref="mobileJWTAuthenticationManager"
create-session="stateless"
use-expressions="true">
<security:custom-filter ref="mobileJWTAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/services/public/**" access="permitAll()"/>
<security:intercept-url pattern="/services/restAPI/**" access="isAuthenticated()" />
</security:http>
<bean id="mobileJWTAuthenticationEntryPoint" class="co.amleto.server.services.security.MobileJWTAuthenticationEntryPoint"/>
<bean id="mobileJWTAuthenticationFilter" class="co.amleto.server.services.security.MobileJWTAuthenticationFilter" >
<constructor-arg name="authenticationManager" ref="mobileJWTAuthenticationManager"/>
<constructor-arg name="entryPoint" ref="mobileJWTAuthenticationEntryPoint"/>
</bean>
<bean id="mobileJWTAuthenticationProvider" class="co.amleto.server.services.security.MobileJWTAuthenticationProvider"/>
<security:authentication-manager alias="mobileJWTAuthenticationManager">
<security:authentication-provider ref="mobileJWTAuthenticationProvider"/>
</security:authentication-manager>
EDIT: My whole code is inspired by this: http://massimilianosciacco.com/spring-security-jwt-authentication. In the AuthenticationFilter I've switched throws with returns. Now I get blank page regardless which url I hit.
Problem solved. As I've mentioned in the edit, my code is based on the solution from the link added in the OP. Custom filter had wrong code: in every situation exceptions were thrown. The solution was to invoke chain.doFilter(request, response) and return from the doFilter method to allow anonymous url invocation.

Spring security session management and Spring MVC view resolver error

I am working on a Spring MVC web application. Last week I started adding Sping Secuirty to my project. The problem I am facing concerns session management.
Here is http part of my spring-security.xml
<http auto-config="true">
<intercept-url pattern="/css" filters="none"/>
<intercept-url pattern="/js" filters="none"/>
<intercept-url pattern="/logout" filters="none"/>
<intercept-url pattern="/loginfailed" filters="none"/>
<intercept-url pattern="/login" filters="none"/>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login" default-target-url="/hello"
authentication-failure-url="/loginfailed" />
<session-management invalid-session-url="/login.jsp?error=sessionExpired" session-authentication-error-url="/login.jsp?error=alreadyLogin">
<concurrency-control max-sessions="1" expired-url="/login.jsp?error=sessionExpiredDuplicateLogin" error-if-maximum-exceeded="false"/>
</session-management>
</http>
Login/logout works fine, but when I try to invalidate user session by trying to login from different browser invalid-session-url="/login.jsp?error=sessionExpired" fails. Browser get redirected, because I see that GET request to login.jsp?error=sessionExpired is being sent. However, web page shows error saying that resource is not available. I suspect that it has something to do with
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
in my dispatcher-servlet.xml. However, I don't know exactly how to fix this issue. login.jsp is located in WEB-INF/pages/
It seems to me Spring MVC DispatcherServlet couldn't find a mapping for /login.jsp because it's not set as a view that accessible without controller. I'm also assuming you had /login mapped to login.jsp (you did not provide enough info to confirm this), but if this is the case, just use expired-url="/login?error=sessionExpiredDuplicateLogin
You are redirecting to the jsp not the mapped url.
session management tag should be :
<session-management invalid-session-url="/login?error=sessionExpired" session-authentication-error-url="/login?error=alreadyLogin">
<concurrency-control max-sessions="1" expired-url="/login?error=sessionExpiredDuplicateLogin" error-if-maximum-exceeded="false"/>
</session-management>

Multiple <http> tags with same authentication manager in Spring Security 3.1

I am using Spring Security 3.1.2
This version allows multiple "http" tags.
I have an application that has two separate login pages, one for user and another for admin. Both of them will use the same authentication manager.
I have build my spring-security.xml in the following manner
<sec:http pattern="/loginForm.jsp" security="none"/>
<sec:http pattern="/loginForm2.jsp" security="none"/>
<sec:http auto-config="true">
<sec:intercept-url pattern="/login1*" access="ROLE_USER" />
<sec:form-login login-page="/loginForm.jsp" default-target-url="/login1"
authentication-failure-url="/loginForm.jsp?login_error=1" />
<sec:logout logout-success-url="/loginForm.jsp" />
</sec:http>
<sec:http auto-config="true">
<sec:intercept-url pattern="/login2*" access="ROLE_ADMIN" />
<sec:form-login login-page="/loginForm2.jsp" default-target-url="/login2"
authentication-failure-url="/loginForm2.jsp?login_error=1" />
<sec:logout logout-success-url="/loginForm2.jsp" />
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="qwertyui" password="123456" authorities="ROLE_USER" />
<sec:user name="asdfghjk" password="123456" authorities="ROLE_USER" />
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
But I am getting this error "A universal match pattern ('/**') is defined before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your namespace or FilterChainProxy bean configuration"
If I omit any one of the tag, it works fine.
If you don't set the pattern attribute on your http element, your http stanza will default to /**, which is a universal match pattern.
I made this mistake myself, because I thought it was only considering the "intercept-url" elements, and none of my intercept-url elements defined a universal match pattern.
Make sure all of your http elements have a pattern attribute defined.
http tag creates security filter chain, default is /**, since you have two of with same default pattern, hence the error, Makes sense, how would spring build filter chains. its duplicate.

Multiple login forms, different authentication managers - latest spring security

I have a web application secured with Spring Security that needs two separate login forms. These two login forms need to be totally independent. I mean different login form, different url paths, be able to have a different authentication manager for each one too.
I have looked all over google and there are some ways to do this, but I have read and see some changes the last couple of weeks should make it easy to do this in the latest snapshot versions of the code.
First of all, as this bug is complete SEC-1171 we can now have multiple namespace elements to support multiple filter chain configurations.
Secondly, as this other bug shows SEC-1847 we are now able to select a custom authentication manager for each http tag.
The problem is that I have downloaded, compiled and everything but my xsd doesn't allow me to create a custom auth manager for each http tag, I also get errors whenever I try to change the login processing url or whenever I try to use a remember me key for each login form.
I started doing something like this:
<!-- Configure realm for administration users -->
<http pattern="/admin/**" auto-config="true" disable-url-rewriting="true" >
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/adminLogin.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/adminLogin.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<!-- Configure realm for standard users -->
<http auto-config="true" disable-url-rewriting="true">
<intercept-url pattern="/user/**" access="ROLE_USER" />
<form-login login-page="/login.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/login.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService" >
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
<authentication-provider>
<password-encoder ref="passwordEncoder"/>
<user-service>
<user name="ned" password="****" authorities="ROLE_USER" />
<user name="tom" password="****" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
I am using the latest snapshot of Spring Security 3.1.
As I said the ideal would be to be able to have two different login forms totally independent using the "new" way that was changed recently on these bugs.
Anybody has worked with this or has any idea?
Thanks in advance.
As you can see in commit log of October 30th'11 (2f67bb3) for SEC-1847, the authentication-manager-ref attribute can be added in http and global-method-security.
Ritesh, you are right, however, if I try to configure authentication-manager-ref in the http element, the follow exception occurs: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'authentication-manager-ref' is not allowed to appear in element 'security:http'.
In header of my security.xml, I'm using http://www.springframework.org/schema/security/spring-security-3.1.xsd. If I browse to this URL, the xsd loaded declares the attribute authentication-manager-ref to the http element, but the xsd in spring-security-config-3.1.0.RC2.jar doesn't.
I created an issue in springsource jira-> https://jira.springsource.org/browse/SEC-1879 .
I replaced the xsd contained in spring-security-config-3.1.0.RC3.jar with a correct one and org.xml.sax.SAXParseException doesn't occur anymore, but it's not possible to declare two authentication-manager beans in security.xml.

Resources