Failing to exclude some URLs from Spring Security protection - java

We have the following spring security configuration:
<bean id="authenticationSuccessHandler" class="***.JsonAuthenticationSuccessHandler"/>
<bean id="logoutSuccessHandler" class="***.web.security.***UrlLogoutSuccessHandler">
<property name="redirectStrategy" ref="noRedirectStrategy"/>
</bean>
<bean id="authenticationFailureHandler"
class="***.web.security.***UrlAuthenticationFailureHandler"/>
<bean id="httpStatusEntryPoint" class="org.springframework.security.web.authentication.HttpStatusEntryPoint">
<constructor-arg value="UNAUTHORIZED"/>
</bean>
<security:http auto-config="true" use-expressions="false" entry-point-ref="httpStatusEntryPoint">
<security:custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrentSessionFilter"/>
<security:form-login
authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-handler-ref="authenticationFailureHandler"
/>
<security:intercept-url pattern="/api/**"/>
<security:anonymous enabled="false"/>
<security:logout logout-url="/logout" delete-cookies="JSESSIONID,sessionId"
success-handler-ref="logoutSuccessHandler"
/>
<security:csrf disabled="true"/>
<security:session-management session-authentication-strategy-ref="sessionAuthenticationStrategy"/>
</security:http>
<bean id="concurrentSessionFilter" class="***.***ConcurrentSessionFilter">
<constructor-arg ref="***SessionRegistry"/>
<constructor-arg ref="errorController"/>
</bean>
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg>
<list>
<ref bean="registerSessionAuthenticationStrategy"/>
<ref bean="concurrentSessionControlAuthenticationStrategy"/>
</list>
</constructor-arg>
</bean>
<bean id="registerSessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg name="sessionRegistry" ref="***SessionRegistry" />
</bean>
<bean id="concurrentSessionControlAuthenticationStrategy" class="***.web.security.***ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg name="sessionRegistry" ref="***SessionRegistry" />
<constructor-arg name="logoutService" ref="logoutService"/>
<property name="maximumSessions" value="1" />
</bean>
<!-- enable spring security annotation processing -->
<security:global-method-security secured-annotations="enabled"/>
<bean id="***LdapAuthenticationProvider" class="***.web.***LdapAuthProvider">
<property name="url" value="${ldap.url}"/>
<property name="filter" value="${ldap.filter}"/>
<property name="domain" value="${ldap.domain}"/>
<property name="dn" value="${ldap.dn}"/>
<property name="ldapEnabled" value="${ldap.enable}"/>
</bean>
<security:authentication-manager>
<security:authentication-provider ref="***LdapAuthenticationProvider"/>
<security:authentication-provider user-service-ref="***UserDetailsService"/>
</security:authentication-manager>
<bean id="usersResource" class="org.springframework.core.io.ClassPathResource">
<constructor-arg value="/users.properties" />
</bean>
<util:property-path id="usersResourceFile" path="usersResource.file" />
<bean id="***UserDetailsService" class="***.web.security.***InMemoryUserDetailsManager">
<constructor-arg index="0" ref="usersResourceFile"/>
</bean>
I tried different ways But I can not find a way to exclude some specific URLs from authentication.
For example:
/api/url/available/without/login
should be available even user is not logged in.
P.S.
I have tried to apply this answer, but it doesn't work for me:
https://stackoverflow.com/a/5382178/2674303
UPD
I have tired
....
<bean id="httpStatusEntryPoint" class="org.springframework.security.web.authentication.HttpStatusEntryPoint">
<constructor-arg value="UNAUTHORIZED"/>
</bean>
<security:http pattern="/api/url/available/without/login" security="none"/>
<security:http auto-config="true" use-expressions="false" entry-point-ref="httpStatusEntryPoint">
....
but when I try to use - this url still locked and I get 401
because this code:
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
String name = authentication != null ? authentication.getName() : "";
throw new BadCredentialsException("Could not find user " + name);
}
throws exception

You just need to add a "default" http interceptor:
<security:http xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/" access="permitAll()"/>
<anonymous/>
<csrf disabled="true"/>
</security:http>
after your current security:http tag. It will handle all requests, which were not handled by the first http construction.

Related

Unable to change Spring security access denied standard response

I have a Spring Boot application in which I used OAuth with Spring Security. When I requests an authorization token to Spring Security it returns the following response:
{"error":"invalid_grant","error_description":"Bad credentials"}
I need to change that response to a custom json, but none of the approaches I have tried works.
I have tried to use a custom AccessDeniedHandler like the following:
public class CustomOAuth2AccessDeniedHandler implements AccessDeniedHandler{
public CustomOAuth2AccessDeniedHandler() {
}
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException authException)
throws IOException, ServletException {
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
response.getOutputStream().println("Exception with message : " + authException.getMessage());
//doHandle(request, response, authException);
}
but it does not get called. Using web.xml to redirect response is not an option for me since I am using Spring Boot, and I do not want to change the format of the response globally.
My spring-security.xml is configured like this:
<!-- Definition of the Authentication Service -->
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="dstest"/>
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="dstest/client"/>
<property name="typeName" value="Basic"/>
</bean>
<!-- <bean id="oauthAccessDeniedHandler" -->
<!-- class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/> -->
<bean id="oauthAccessDeniedHandler"
class="in.robotrack.brad.config.CustomOAuth2AccessDeniedHandler"/>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<!-- Authentication in config file -->
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="customUserDetailsService">
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices"/>
</bean>
try bellow:
HttpSecurity http = ...
http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);
if you don't want to define your custom AccessdeniedHandler then even you can try this
HttpSecurity http = ...
http.exceptionHandling().accessDeniedPage("/403");
And then in your controller just define one method that can handle /403 request mapping and there you just return your 403 error page, as you do in normal methods inside any controller class.

Spring FilterChainProxy with filterSecurityInterceptor not working correctly?

I have a spring application with the config files as shown below. All configs seem correct but while debugging I found that, during the initialization spring creates two beans for FilterSecurityInterceptor one without any intercept-url rules and the other with the rules that I have specified.
When a request comes, it uses the FilterSecurityInterceptor bean with no intercept-url rules. So I see the following log:
DEBUG FilterSecurityInterceptor:183 - Public object - authentication not attempted
But the request URL falls under the intercept URL rule. I debugged and found that this is because the bean used didn't have any intercept rules in httpMethodMap of DefaultFilterInvocationSecurityMetadataSource.
I am not sure what is wrong here.
Below is the applicationContext-security.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"
default-init-method="init">
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
user-service-ref="userDetailService">
</security:authentication-provider>
</security:authentication-manager>
<alias name="filterChainProxy" alias="springSecurityFilterChain" />
<bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<bean id="consoleAuthenticationSuccessHandler"
class="custom_class">
<property name="defaultTargetUrl" value="/loginSuccess.htm" />
<property name="targetUrlParameter" value="targetURL" />
</bean>
<bean id="consoleAuthenticationFailureHandler"
class="custom_class">
<property name="loginFailureUrl" value="/loginFailure.htm" />
</bean>
<bean id="consoleLogoutSuccessHandler"
class="custom_class">
<property name="logoutUrl" value="/loggedout.htm" />
</bean>
<bean id="userDetailService"
class="custom_class">
</bean>
<security:http auto-config="true"
security-context-repository-ref="securityContextRepository">
<security:form-login authentication-failure-url="/loginFailure.htm"
default-target-url="/loginSuccess.htm"
authentication-success-handler-ref="consoleAuthenticationSuccessHandler" />
<security:logout success-handler-ref="consoleLogoutSuccessHandler" />
<security:anonymous enabled="false" />
<security:session-management
session-fixation-protection="none" />
</security:http>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/login.htm*"
filters="none" />
<security:filter-chain pattern="/**"
filters="securityContextFilter, logoutFilter, formLoginFilter, servletApiFilter, exceptionTranslator, filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="securityContextFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository" ref="securityContextRepository" />
</bean>
<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg ref="consoleLogoutSuccessHandler"
index="0"
type="org.springframework.security.web.authentication.logout.LogoutSuccessHandler" />
<constructor-arg>
<list>
<bean
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</list>
</constructor-arg>
</bean>
<bean id="servletApiFilter"
class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
<bean id="exceptionTranslator"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp" />
</bean>
</property>
</bean>
<bean id="formLoginFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="consoleAuthenticationSuccessHandler" />
<property name="authenticationFailureHandler" ref="consoleAuthenticationFailureHandler" />
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/login.htm*"
access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:filter-security-metadata-source>
</property>
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
</beans>
Appreciate any help here.
You have <security:http> element in the config. From the documentation:
38.1.2 <http>
Each <http> namespace block always creates an SecurityContextPersistenceFilter, an ExceptionTranslationFilter and a FilterSecurityInterceptor. These are fixed and cannot be replaced with alternatives.
So your <bean id="filterSecurityInterceptor"> is ignored. Instead of
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/login.htm*"
access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:filter-security-metadata-source>
</property>
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
you should change <security:http> to include something like
<security:http ...
authentication-manager-ref="authenticationManager">
...
<security:intercept-url pattern="/login.htm*"
access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:http>
You don't need <bean id="accessDecisionManager">, because (quote from the docs) "by default an AffirmativeBased implementation is used for with a RoleVoter and an AuthenticatedVoter", which is exactly what you define.
Also your <bean id="securityContextFilter"> is ignored, instead you should add security-context-repository-ref="securityContextRepository" attribute to http element.
And your <bean id="exceptionTranslator"> is ignored, I'm not sure how to replace it properly.
And you manually define a lot of org.springframework.security beans. I suspect that most of them are either unnecessary (defined by default), or should be defined using specialized elements of security: namespace, instead of raw spring beans.

Remember-me don't work(with Spring security 3.1, LDAP, ActiveDirectory)

I'm trying to cofigure "remember-me" in my web app. I use Spring security 3.1, LDAP and ActiveDirectory. This is applicationcontext-security.xml:
<!-- LDAP server details -->
<authentication-manager>
<authentication-provider ref="ldapActiveDirectoryAuthProvider" />
</authentication-manager>
<!-- enable security tag libraries on jsp pages -->
<beans:bean id="grantedAuthoritiesMapper" class="xxcutxx.spring.security.ActiveDirectoryGrantedAuthoritiesMapper"/>
<beans:bean id="ldapActiveDirectoryAuthProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="xxcutxx" />
<beans:constructor-arg value="xxcutxx" />
<beans:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
<beans:property name="useAuthenticationRequestCredentials" value="true" />
<beans:property name="convertSubErrorCodesToExceptions" value="true" />
</beans:bean>
<http pattern="/index.jsp*" security="none"/>
<http pattern="/img/**" security="none"/>
<http pattern="/css/**" security="none"/>
<http pattern="/js/**" security="none"/>
<beans:bean id="successHandler" class="xxcutxx.spring.security.CustomAuthenticationSuccessHandler"/>
<beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<http access-decision-manager-ref="accessDecisionManager" auto-config="true" pattern="/**"> <!--"-->
<!-- Login pages -->
<form-login login-page="/index.jsp" default-target-url="xxcutxx" authentication-success-handler-ref="successHandler"
login-processing-url="/j_spring_security_check" authentication-failure-url="/index.jsp?loginerr=1" />
<logout logout-success-url="/index.jsp"/>
<access-denied-handler error-page="/index.jsp?loginerr=3"/>
<intercept-url pattern="/*.do" access="READER" />
<remember-me key="MY_REMEMBER_ME_KEY" services-ref="rememberMeServices"/>
</http>
And this is applicationcontext.xml:
<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="key" value="MY_REMEMBER_ME_KEY" />
<property name="cookieName" value="MY_REMEMBER_ME_COOKIE" />
<property name="parameter" value="remember" />
<property name="tokenValiditySeconds" value="1209600" />
<property name="userDetailsService" ref="MyUserDetailsService" />
<property name="alwaysRemember" value="false" />
</bean>
<bean id="MyUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg index="0" ref="ldapUserSearch"/>
</bean>
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" type="String">
<value>
xxcutxx
</value>
</constructor-arg>
<constructor-arg index="1" type="String" value="(objectCategory=Person)">
</constructor-arg>
<constructor-arg index="2" ref="ldapPoolContext"/>
</bean>
<bean id="ldapPoolContext" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="xxcutxx"/>
<property name="pooled" value="false"/>
</bean>
The web app starts but don't create the cookie and seems remember me does not work.
Where is the error and/or something is missing? i don't understand what i must to do
THX for HELP!!

The matching wildcard is strict, but no declaration can be found for element 'bean'

I am trying to integrate a Spring Security project with CAS server for authentication by configuring the CAS client. Before applying it to my web app I tried it to the Spring Security sample project.
I added the CAS plugins as indicated here https://wiki.jasig.org/display/CASC/Configuring+the+JA-SIG+CAS+Client+for+Java+using+Spring adapting it to the case.
When I run or debug the sample web app I receive the error I mentioned on the title which is referred to the line
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
of the following spring-security.xml:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin**" 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>
<!-- Select users and user_roles from database -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service id="userService" data-source-ref="dataSource"
users-by-username-query=
"select username,password, enabled from users where username=?"
authorities-by-username-query=
"select username, role from user_roles where username =? " />
</authentication-provider>
</authentication-manager>
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/" filters="casValidationFilter, wrappingFilter" />
<security:filter-chain pattern="/secure/receptor" filters="casValidationFilter" />
<security:filter-chain pattern="/j_spring_security_logout" filters="logoutFilter,etf,fsi" />
<security:filter-chain pattern="/**" filters="casAuthenticationFilter, casValidationFilter, wrappingFilter, sif,j2eePreAuthFilter,logoutFilter,etf,fsi"/>
</security:filter-chain-map>
</bean>
<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
<bean id="preAuthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userService"/>
</bean>
</property>
</bean>
<bean id="preAuthEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="j2eePreAuthFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationDetailsSource">
<bean class="org.springframework.security.web.authentication.WebAuthenticationDetailsSource" />
</property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/"/>
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<bean id="servletContext" class="org.springframework.web.context.support.ServletContextFactoryBean"/>
<bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="preAuthEntryPoint"/>
</bean>
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource">
<security:filter-invocation-definition-source>
<security:intercept-url pattern="/**" access="ROLE_ANONYMOUS,ROLE_USER"/>
</security:filter-invocation-definition-source>
</property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>
<bean class="org.jasig.cas.client.validation.Saml11TicketValidator" id="ticketValidator">
<constructor-arg index="0" value={cas.login} />
<!--<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />-->
<!--<property name="proxyCallbackUrl" value="http://localhost:8080/ui/" />-->
</bean>
<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
<bean id="casAuthenticationFilter" class="org.jasig.cas.client.authentication.AuthenticationFilter">
<property name="casServerLoginUrl" value={cas.login.url} />
<property name="serverName" value={cas.login.url} />
</bean>
<bean id="casValidationFilter" class="org.jasig.cas.client.validation.Saml11TicketValidationFilter">
<property name="serverName" value="http://localhost:8080/ui" />
<property name="exceptionOnValidationFailure" value="true" />
<!--<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />-->
<property name="redirectAfterValidation" value="true" />
<property name="ticketValidator" ref="ticketValidator" />
<!--<property name="proxyReceptorUrl" value="/secure/receptor" />-->
</bean>
<bean id="wrappingFilter" class="org.jasig.cas.client.util.HttpServletRequestWrapperFilter" />
</beans:beans>
Any help is appreciated.
You need to add XSD in schema location as well.
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"

Implement SSO using CAS + Spring Security

I'm trying to implement SSO across several web applications using CAS and Spring Security. Expected case:
CAS - http:// localhost:8080/cas/
App A protected content - http: //localhost:8081/cas-client1/secure/index.html
App B protected content - http: //localhost:8081/cas-client2/secure/index.html
1) When user access cas-client1, CAS login form will be prompted and trigger authentication.
2) The same user access cas-client2, previous login should be recognized and no login form will be prompted
However, I am failed to implement step 2. CAS login form still prompted to user and therefore requires double login. Is there any wrong setting in my Spring Security configuration:
<security:http entry-point-ref="casAuthenticationEntryPoint" auto-config="true">
<security:intercept-url pattern="/secure/**" access="ROLE_USER" />
<security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />
</security:http>
<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="http://localhost:8080/cas/login" />
<property name="serviceProperties" ref="serviceProperties" />
</bean>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<!-- http://localhost:8081/cas-client2 for app 2-->
<property name="service" value="http://localhost:8081/cas-client1/j_spring_cas_security_check" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/casfailed.jsp" />
</bean>
</property>
</bean>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="userDetailsService" ref="userService" />
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="http://localhost:8080/cas" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only" />
</bean>
<security:user-service id="userService">
<security:user name="wilson" password="wilson" authorities="ROLE_USER" />
</security:user-service>
The problem is finally solved. My CAS is using HTTP and therefore need to set secure cookies to false.
Modify ticketGrantingTicketCookieGenerator.xml
p:cookieSecure="false"

Categories

Resources