Spring Security all rolles except anonymous - spring-security

hi i have an spring security application
<http auto-config="true">
<intercept-url pattern="/**" />
<form-login authentication-failure-handler-ref="authenticationFailureHandler" authentication-success-handler-ref="authenticationSuccessHandler" login-page="${loginUrl}" authentication-failure-url="${loginUrl}" />
<logout logout-url="/logout" invalidate-session="true" success-handler-ref="logoutSuccessHandler" />
<anonymous enabled='false'/>
</http>
but anonymous user is not intercepted, how can i allow all roles but not ROLE_ANONYMOUS?

Try IS_AUTHENTICATED_FULLY:
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
You can do the same thing using SpEL expression:
<http auto-config="true" use-expressions="true">
...
<intercept-url pattern="/**" access="isAuthenticated()" />
...
</http>
All available expressions are listed here.
In general SpEL expressions are more flexible.

Related

Spring Security 4 returns pages as plain/text

I'm migrating from Spring Security 3 to 4 and have an issue with header type of returning page - by default it comes as text/plain and as a result I see just html text instead of real page. In Spring Security 3 everything was working fine
<http pattern="/images/**" security="none"/>
<http pattern="/css/**" security="none"/>
<http pattern="/xml/**" security="none"/>
<http pattern="/**" use-expressions="true"
authentication-manager-ref="authenticationManager"
disable-url-rewriting="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<access-denied-handler ref="accessDeniedHandler"/>
<form-login login-page="/pages/home/login.html"
default-target-url="/pages/home/entry.html" authentication-failure-handler-ref="authenticationFailureHandler"
always-use-default-target="true"
authentication-details-source-ref="authenticationDetailsSource"/>
<logout logout-success-url="/pages/home/login.html" invalidate-session="true"/>
<intercept-url pattern="/pages/home/**" access="hasRole('ROLE_CLIENT') or hasRole('ROLE_ANONYMOUS_CLIENT')"/>
<intercept-url pattern="/pages/admin/**" access="hasRole('ROLE_ADMIN')"/>
<session-management invalid-session-url="/pages/home/login.html"/>
<anonymous enabled="false"/>
<custom-filter ref="anonymousAuthenticationFilter" position="ANONYMOUS_FILTER"/>
<custom-filter before="CAS_FILTER" ref="oauthFilter"/>
</http>
<beans:bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/pages/home/login.html"/>
</beans:bean>
<beans:bean id="authenticationFailureHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/pages/home/login.html"/>
</beans:bean>

403 errors after upgrading to Spring Security 4.0.0

I've been trying to update my project to Spring Security 4.0.0. I think I've read the migration guide quite extensively but even if I can successfully login and navigate through the pages, I get 403 errors on every Ajax requests. Everything is working fine with 3.2.7.
This is my "manual login" configuration file:
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- HTTP security configurations -->
<http use-expressions="true" auto-config='true' disable-url-rewriting="false">
<intercept-url access="permitAll" pattern="/" /><!-- To permit "/" allows the use of web.xml's <welcome-file> -->
<intercept-url access="permitAll" pattern="/home" />
<intercept-url access="permitAll" pattern="/login" />
<intercept-url access="permitAll" pattern="/pages/exceptions/**" />
<intercept-url access="permitAll" pattern="/javax.faces.resource/**" />
<intercept-url access="permitAll" pattern="/resources/**" />
<intercept-url access="permitAll" pattern="/j_spring_security_check"/>
<intercept-url access="hasRole('ROLE_ADMIN')" pattern="/administration/**" />
<intercept-url access="isAuthenticated()" pattern="/**" />
<logout logout-url="/logout" logout-success-url='/home' />
<form-login login-page='/login'
username-parameter="j_username"
password-parameter="j_password"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/login?auth=fail"
default-target-url="/home" />
</http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="${authentication.provider}" />
</authentication-manager>
<b:bean name="bcryptEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<b:bean id="daoAuthProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService">
<b:bean class="eu.ueb.acem.services.auth.DaoUserDetailsService">
<b:property name="domainService" ref="domainService" />
</b:bean>
</b:property>
<b:property name="passwordEncoder" ref="bcryptEncoder" />
</b:bean>
</b:beans>
I try to use:
<http use-expressions="true" auto-config='true' disable-url-rewriting="false">
<headers disabled="true" />
<csrf disabled="true"/>
...
</http>
but I get :
cvc-complex-type.3.2.2: Attribute 'disabled' is not allowed to appear in element 'headers'
cvc-complex-type.3.2.2: Attribute 'disabled' is not allowed to appear in element 'csrf'
which is normal because 4.0.0 has no dedicated XML Schema at:
http://www.springframework.org/schema/security/
So what could possibly cause these "403 forbidden" errors?
Ok, I found the solution. It is indeed to use:
<http use-expressions="true" auto-config='true' disable-url-rewriting="false">
<csrf disabled="true"/>
...
</http>
but for the time being, we have to ignore the XML Schema error in Eclipse. Hopefully Spring will put their new Schema online soon.

Spring Security Preauth "filters=none" not working

strange one,
I am using spring security with siteminder and it works fine. However I want to have one url which isn't protected - our loadBalancer needs a "healthCheck" url within the app itself. This url isn't intercepted by siteminder, but spring security seems to apply the preauth to it anyhow..
if I run it locally using a simple forms-based security config the following works (excluding the filters):
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/html/healthCheck.html" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/login" filters="none" />
<intercept-url pattern="/favicon.ico" filters="none" />
<intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
In this case, I can browse to localhost/myApp/resources/html/healthCheck.html without hitting an authorization issue, but any other url will display the login form. All looking good so far!
However when I deploy to the server I am using the following config:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/html/healthCheck.html" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/login" filters="none" />
<intercept-url pattern="/favicon.ico" filters="none" />
<intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
<custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>
When I browse to: server/myapp/resources/html/healthCheck.html I get the following error:
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
org.springframework.security.core.userdetails.User.<init>(User.java:94)
com.myApp.security.SecuritySBSUserDetailsService.loadUserByUsername(SecuritySBSUserDetailsService.java:119)
org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:53)
I think this is caused by the UserDetailsService getting instantiated without any SM_USER. Yet the filters=none is in place.. and works when using forms authentication..Any idea what might be causing this, or better - of a workaround?
By the way, my userdetails service is configured as follows:
<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<beans:property name="principalRequestHeader" value="SM_USER" />
<beans:property name="exceptionIfHeaderMissing" value="false" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
i.e. I've set exceptionIfHeaderMissing to false, if that helps..
The most obvious thing I can see is that /resources/html/healthCheck.html won't be matched by /html/healthCheck.html. If you are rewriting the URLs somewhere you should probably explain that.
If you enable debug logging, it should explain in detail what is matched against what.
I'd also leave out the auto-config. It causes more confusion than it is worth. And you should use /** rather than /* for a universal ant pattern match.
It's probably also worth mentioning here that Spring Security 3.1 has a better approach for defining empty filter chains, and also allows you to define more than one filter chain using the <http> syntax.
Okay, it seems to be a bug in spring security as far as I can see. I got around it by adding a dummy return to the start of the loadUserByName method in the UserDetailsService..
#Override
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException, DataAccessException {
logger.trace(">> loadUserByUsername()");
logger.info("-- loadUserByUsername(): username : {}", userName);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
if(userName==null || userName.trim().equals("")) {
return(new User("ANONYMOUS", "", true, true, true, true, authorities));
}
// rest of auth checks
It would seem like with the config I have, the UserDetails check shouldn't be getting triggered at all (as it is with the forms..). If anyone has a configuration based workaround I'll give you a plus :-)

Mapping each http block to a specific Authentication Provider

I would like to base my Spring Security configuration depending on the user's context path. If the user goes against a url with http://path1/resource1 I would like to direct them to a specific authentication provider. If they come in on http://path2/resource2 I would like to direct them to a different authentication provider. These url paths are REST based web services calls so that's why they're stateless and not coming from a form. Currently, all authentication providers get executed. What is the best approach for this situation? I'm using spring-security 3.1.0.M1.
<http pattern="/path1/**" create-session="stateless">
<intercept-url pattern="/**" access="ROLE_USER,ROLE_VAR,ROLE_ADMIN" />
<http-basic />
</http>
<http pattern="/path2/**" create-session="stateless">
<intercept-url pattern="/**" access="ROLE_USER,ROLE_VAR,ROLE_ADMIN" />
<http-basic />
</http>
You can define an authentication-manager reference in each http block:
<http pattern="/api/**" authentication-manager-ref="apiAccess">
...
</http>
<http auto-config = "true" authentication-manager-ref="webAccess">
...
</http>
<!-- Web authentication manager -->
<authentication-manager id="webAccess">
<authentication-provider
user-service-ref="userService">
</authentication-provider>
</authentication-manager>
<!-- API authentication manager -->
<authentication-manager id="apiAccess">
<authentication-provider
user-service-ref="developerService">
</authentication-provider>
</authentication-manager>
This feature has been added in Spring Security 3.1.
This works for me:
<security:authentication-manager alias="basicAuthenticationManager">
<security:authentication-provider user-service-ref="accountService">
<security:password-encoder hash="sha"/>
</security:authentication-provider>
<security:authentication-provider user-service-ref="accountService"/>
</security:authentication-manager>
<bean id="basicProcessingFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager">
<ref bean="basicAuthenticationManager" />
</property>
<property name="authenticationEntryPoint">
<ref bean="basicProcessingEntryPoint" />
</property>
</bean>
<bean id="basicProcessingEntryPoint"
class="com.yourpackage.web.util.CustomBasicAuthenticationEntryPoint">
<property name="realmName" value="yourRealm" />
</bean>
<!-- Stateless RESTful service using Basic authentication -->
<security:http pattern="/rest/**" create-session="stateless" entry-point-ref="basicProcessingEntryPoint">
<security:custom-filter ref="basicProcessingFilter" position="BASIC_AUTH_FILTER" />
<security:intercept-url pattern="/rest/new" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/rest/**" access="ROLE_USER" />
</security:http>
<!-- Additional filter chain for normal users, matching all other requests -->
<security:http use-expressions="true">
<security:intercept-url pattern="/index.jsp" access="permitAll" />
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:form-login login-page="/signin"
authentication-failure-url="/signin?signin_error=1"
default-target-url="/"
always-use-default-target="true"/>
<security:logout />
</security:http>
I implemented the authentication entry point because I needed to send some special error codes in certain situations but you don't need to do so.

Spring Security - How can I specify anonymous role to root page

The default URL for my web app is http://localhost:8080/Icd/
I want to display my custom login page which is /index.jsp.
However , when I configure the spring security to do so , I am getting too many redirects problem . Below the code present in the security.xml file .
Let me know if I am missing something .
<security:http auto-config="true" >
<security:intercept-url pattern="/" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/*" access="ROLE_USER" />
<security:form-login login-page="/index.jsp" />
</security:http>
<security:authentication-provider>
<security:user-service>
<security:user name="david" password="david" authorities="ROLE_USER,ROLE_ADMIN" />
<security:user name="alex" password="alex" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
When you put
<security:intercept-url pattern="/*" access="ROLE_USER" />
you're saying that every page requires ROLE_USER to be accessed (which includes the login page itself)
This (untested) may do the trick:
<security:intercept-url pattern="/index.jsp" access="permitAll"/>
<security:intercept-url pattern="/*" access="ROLE_USER" />
Try specifying your configuration like the following:
<security:http auto-config="true" use-expressions="true" access-denied-page="/krams/auth/denied" >
<security:intercept-url pattern="/krams/auth/login" access="permitAll"/>
<security:intercept-url pattern="/krams/main/admin" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/krams/main/common" access="hasRole('ROLE_USER')"/>
<security:form-login
login-page="/krams/auth/login"
authentication-failure-url="/krams/auth/login?error=true"
default-target-url="/krams/main/common"/>
<security:logout
invalidate-session="true"
logout-success-url="/krams/auth/login"
logout-url="/krams/auth/logout"/>
</security:http>
This one uses a custom login page. For more info, you can check the full application at http://krams915.blogspot.com/2010/12/spring-security-3-mvc-using-simple-user.html

Resources