After updating spring security from 3.2.5 to 5.5.7 in keycloak implementation, on logout, it is redirecting to
sso/j_spring_security_logout and saying the page is not found.
spring security xml
<!-- Keycloak Security for UI -->
<security:http pattern="/sso/**" auto-config="false" use-expressions="true" entry-point-ref="keycloakAuthenticationEntryPoint" authentication-manager-ref="authenticationManagerKeycloak">
<security:custom-filter ref="keycloakAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/sso/**" access="hasAuthority('ROLE_ADMIN')" />
<security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
</security:http>
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg name="logoutSuccessUrl" value="/sso" />
<beans:constructor-arg name="handlers" >
<beans:list>
<beans:ref bean="keycloakLogoutHandler" />
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</beans:list>
</beans:constructor-arg>
<beans:property name="logoutRequestMatcher">
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<beans:constructor-arg name="pattern" value="/sso/j_spring_security_logout" />
<beans:constructor-arg name="httpMethod" value="POST" />
</beans:bean>
</beans:property>
</beans:bean>
I have a requirement to redirect to login page when session expires for a logged in user.
However the functionality is accessible as anonymous user (i.e the user not logged in) as well.
A feature "Search Address" is accessible by everyone, meaning logged in users and anonymous users (user not logged in)....
So the requirement is such, that when the user logs in and performs search, it should redirect if session has already expired, however just making it clear the same search should work if we don't login in (i.e anonymous).
An anonymous user is technically logged in, therefore they have a session created as well, however they wouldn't manually type user name/password in to login as opposed to the logged in user
<?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http security="none"
pattern="^/(login\.jsp|customSkin|openlayers|images|js)[/\?].*$"
request-matcher="regex"/>
<security:http entry-point-ref="http403ForbiddenEntryPoint">
<security:anonymous enabled="true" granted-authority="ROLE_GENERIC" />
<security:custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter"/>
<security:custom-filter position="PRE_AUTH_FILTER" ref="PreAuthenticationFilter"/>
<!-- <security:logout logout-success-url="/loginUI.jsp" /> -->
<security:logout logout-url="/logout" success-handler-ref="LogoutSuccessHandler" />
<security:session-management session-authentication-strategy-ref="sessionAuthenticationStrategy"/>
<!-- SMES Interceptors -->
<security:intercept-url pattern="/Mark**" access="ROLE_ABC_OSGV" />
<security:intercept-url pattern="/abc/admin/**" access="ROLE_ABC_OSGV" />
<security:intercept-url pattern="/abc/edit/**" access="ROLE_ABC_OSGV,ROLE_ABC_REGISTERED_USER" />
<security:intercept-url pattern="/abclookup/**" access="ROLE_ABC_OSGV,ROLE_ABC_REGISTERED_USER,ROLE_GENERIC,ROLE_ADMIN,ROLE_EDIT,ROLE_ABC_ADMIN,ROLE_ABC_HCA" />
<security:intercept-url pattern="/general/**" access=
"ROLE_ABC,
ROLE_GENERIC,
ROLE_ADMIN,
ROLE_ABC_EXPORT,
ROLE_EDIT,
ROLE_ABC,
ROLE_ABC_TPC,
ROLE_ABC_VMT,
ROLE_ABC_S,
ROLE_ABC_DATA_GENERIC,
ROLE_ABC_DATA_ADMIN,
ROLE_ABC_OSGV,
ROLE_ABC_REGISTERED_USER,
ROLE_ABC_ADMIN,
ROLE_ABC_HCA,
ROLE_ABC_NAMES" />
<!-- SMES Interceptors -->
<security:intercept-url pattern="/vicnames/edit/**" access="ROLE_ABC_ADMIN,ROLE_ABC_HCA" />
<security:intercept-url pattern="/vicnames/admin/**" access="ROLE_ABC_ADMIN" />
<!-- LASSI Interceptors -->
<security:intercept-url pattern="/edit/**" access="ROLE_ADMIN,ROLE_EDIT" />
<security:intercept-url pattern="/broadcast/save**" access="ROLE_EDIT" />
<security:intercept-url pattern="/edmbooking/admin/**" access="ROLE_ABC_BOOKING_ADMIN" />
<security:intercept-url pattern="/adminUdateLogicaLabels**" access="ROLE_ADMIN,ROLE_EDIT" />
<security:intercept-url pattern="/**" access=
"ROLE_DQA,
ROLE_GENERIC,
ROLE_ADMIN,
ROLE_DQA_EXPORT,
ROLE_EDIT,
ROLE_APS,
ROLE_ABC_TPC,
ROLE_ABC_VMT,
ROLE_ABC_TEST,
ROLE_ABC_DATA_GENERIC,
ROLE_ABC_DATA_ADMIN,
ROLE_ABC_OSGV,
ROLE_ABC_REGISTERED_USER,
ROLE_ABC_ADMIN,
ROLE_ABC_HCA,
ROLE_ABC_NAMES" />
<security:access-denied-handler ref="accessDeniedHandler"/>
</security:http>
<bean id="LogoutSuccessHandler"
class="LogoutHandlerImpl">
</bean>
<bean id="http403ForbiddenEntryPoint"
class="CustomHttp403ForbiddenEntryPoint">
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preAuthenticationProvider" />
<security:authentication-provider ref="myProfileAuthenticationProvider" />
</security:authentication-manager>
<bean id="preAuthenticationFilter" class="PreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="formLoginFilter" class="UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref = "authenticationSuccessHandler"/>
<property name="authenticationFailureHandler" ref = "authenticationFailureHandler" />
</bean>
<bean id="authenticationSuccessHandler"
class="AuthenticationSuccessHandlerImpl">
<!--<property name="defaultTargetUrl" value="/login.jsp"/>-->
<property name="alwaysUseDefaultTargetUrl" value="true" />
</bean>
<bean id="authenticationFailureHandler"
class="AuthenticationFailureHandler">
<!-- <property name="defaultFailureUrl" value="/sessionTimeout.jsp?login_error=true"/> -->
<property name="defaultFailureUrl" value="/login.jsp?login_error=true"/>
</bean>
<bean id="preAuthenticationProvider"
class="PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="lpreAuthenticatedUserDetailsService"/>
</bean>
<bean id="lpreAuthenticatedUserDetailsService" class="somepreauthenticateduserdetailsservice"/>
<bean id="myProfileAuthenticationProvider"
class="com.test.AuthenticationProvider">
<property name="serviceInvoker" ref="authenticationServiceInvoker" />
<property name="roleMapping">
<map>
<entry key="ABC_DQA" value="ROLE_DQA" />
<entry key="ABC_APS" value="ROLE_APS" />
<entry key="ABC_EDIT" value="ROLE_EDIT" />
<entry key="ABC_ADMINISTRATOR" value="ROLE_ADMIN" />
<entry key="ABC_GENERIC" value="ROLE_GENERIC" />
<entry key="ABC_DQA_EXPORT" value="ROLE_DQA_EXPORT" />
<entry key="ABC_FOH" value="ROLE_ABC_FOH" />
<entry key="ABC_TPC" value="ROLE_ABC_TPC" />
<entry key="ABC_VMT" value="ROLE_ABC_VMT" />
<entry key="ABC_SPEAR" value="ROLE_ABC_TEST" />
<entry key="ABC_LANDATA_GENERIC" value="ROLE_ABC_DATA_GENERIC" />
<entry key="ABC_LANDATA_ADMIN" value="ROLE_ABC_DATA_ADMIN" />
<entry key="ABC_OSGV" value="ROLE_ABC_OSGV" />
<entry key="ABC_Registered_Users" value="ROLE_ABC_REGISTERED_USER" />
<entry key="ABC_ADMINISTRATOR_ROLE" value="ROLE_ABC_ADMIN" />
<entry key="ABC_HISTORIAN_ROLE" value="ROLE_ABC_HCA" />
<entry key="ABC_PUBLIC_ROLE" value="ROLE_ABC_NAMES" />
<entry key="ABC_BOOKING_ADMIN" value="ROLE_EDM_BOOKING_ADMIN" />
</map>
</property>
</bean>
<bean id="accessDeniedHandler"
class="someaccessdeniedhandler">
<property name="errorPage" value="/login.jsp?access_denied=true"/>
</bean>
<bean id="authenticationServiceInvoker"
class="com.test.AuthenticationServiceInvoker" />
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
<property name="maximumSessions" value="1"/>
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
</beans>
public class CustomHttp403ForbiddenEntryPoint implements AuthenticationEntryPoint {
private static final Log logger = LogFactory.getLog(Http403ForbiddenEntryPoint.class);
/**
* Always returns a 403 error code to the client.
*/
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-authenticated entry point called. Rejecting access");
}
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (request.getUserPrincipal() == null && request.getContentType() != null && request.getContentType().toLowerCase().indexOf("multipart/form-data") > -1 ) {
returnJSSCript(request, response, "{\"sessionTimeout\":\"true\"}");
}
else {
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
}
}
private void returnJSSCript(HttpServletRequest req, HttpServletResponse response, String msg){
response.setContentType("text/html");
try {
String eventName = "sessionTimeout";
PrintWriter out = response.getWriter();
out.println("<script type=\"text/javascript\">");
out.println("parent.fireEvent('" + eventName + "','" + msg + "');");
out.println("</script>");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Could you please let me know how we can redirect to a login page when the user's session has been expired without breaking the search functionality of allowing the anonymous user to still perform the search in Spring Security.
Cheers,
Tech XX
Just make the search url anon, and take it out to another http configuration, So it will not be filtered in your /** chain(<security:http entry-point-ref="http403ForbiddenEntryPoint">).
<security:http pattern="/general/search.json" security="none"/>
I have been trying to implement spring security 3.0 remember me service in my application but unfortunately couldn't get it working.
I didn't find any specific example related to this, not even in spring documentation. It would be nice if somebody can give a working example code. Please find code of my spring-security.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http entry-point-ref="myAuthenticationEntryPoint">
<security:session-management
session-fixation-protection="newSession" />
<security:custom-filter position="FORM_LOGIN_FILTER"
ref="processingFilter" />
<security:logout logout-url="/logout"
logout-success-url="/login" />
<security:intercept-url pattern='/index.jsp'
filters='none' />
<security:intercept-url pattern='/login*'
filters='none' />
<security:remember-me key="springrocks" />
<security:intercept-url pattern='/admin/**'
access="ROLE_ADMIN" />
</security:http>
<security:authentication-manager>
<security:authentication-provider
ref="myAuthenticationProvider"></security:authentication-provider>
</security:authentication-manager>
<bean id="myAuthenticationProvider"
class="example.AuthenticationProviderExtended">
</bean>
<bean id="authenticationManager" class="example.AuthenticationManagerExtended" />
<bean id="processingFilter" class="example.FormBasedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="usernameParameter" value="username" />
<property name="passwordParameter" value="password" />
<property name="allowSessionCreation" value="true" />
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler" />
<property name="authenticationSuccessHandler" ref="simpleUrlAuthenticationSuccessHandler" />
<property name="filterProcessesUrl" value="/performLogin" />
</bean>
<bean id="simpleUrlAuthenticationFailureHandler" class="example.AuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login"></property>
</bean>
<bean id="simpleUrlAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/home" />
</bean>
<bean id="myAuthenticationEntryPoint"
class="example.CustomAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login" />
</bean>
<bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService" />
<property name="key" value="springRocks" />
</bean>
<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="springRocks" />
</bean>
<bean id="myUserDetailsService" class="example.MyCustomeUserDetailsService">
</bean>
</beans>
Please look the Spring Security documentation here:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#remember-me-hash-token
You need to make sure your form contains a checkbox (or other types of input with) the remember me attribute name
<input type="checkbox" name="_spring_security_remember_me"/>
This attribute is configurable via remember-me-parameter on xml, eg:
<remember-me remember-me-parameter="please_remember"/>
Please help with the following error that I get with Spring Security 3.05 and Tomcat7.0. I am new to spring security and am using the below tutorial:
Simple web application with Spring Security: http://heraclitusonsoftware.wordpress.com/software-development/spring/simple-web-application-with-spring-security-part-6/
Here is the error:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoAuthenticationProvider' defined in ServletContext resource [/WEB-INF/applicationContext-security.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframework.security.core.userdetails.memory.InMemoryDaoImpl' to required type 'org.springframework.security.userdetails.UserDetailsService' for property 'userDetailsService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.core.userdetails.memory.InMemoryDaoImpl] to required type [org.springframework.security.userdetails.UserDetailsService] for property 'userDetailsService': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:563)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:872)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframework.security.core.userdetails.memory.InMemoryDaoImpl' to required type 'org.springframework.security.userdetails.UserDetailsService' for property 'userDetailsService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.core.userdetails.memory.InMemoryDaoImpl] to required type [org.springframework.security.userdetails.UserDetailsService] for property 'userDetailsService': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:471)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1363)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
... 19 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.springframework.security.core.userdetails.memory.InMemoryDaoImpl] to required type [org.springframework.security.userdetails.UserDetailsService] for property 'userDetailsService': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:291)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:155)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:461)
... 23 more
My spring security config and listed below:
<?xml version="1.0" encoding="UTF-8"?>
<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"
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.0.xsd">
<!--<global-method-security secured-annotations="disabled">
</global-method-security>
<http auto-config="true">
<intercept-url pattern="/login.jsp" filters="none" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp"
default-target-url="/home.htm" always-use-default-target="false"
authentication-failure-url="/login.jsp?authfailed=true"/>
<logout invalidate-session="true" logout-url="/logout.htm"
logout-success-url="/login.jsp?loggedout=true"/>
<session-management session-fixation-protection="newSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
</http>
<authentication-manager>
<authentication-provider>
<user-service id="userDetailsService">
<user name="username" password="password" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="test" password="test" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>-->
<beans:bean id="sessionRegistry"
class="org.springframework.security.concurrent.SessionRegistryImpl" />
<beans:bean id="defaultConcurrentSessionController"
class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="exceptionIfMaximumExceeded"
value="true" />
</beans:bean>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="hideUserNotFoundExceptions"
value="false" />
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider" />
</beans:list>
</beans:property>
<beans:property name="sessionController"
ref="defaultConcurrentSessionController" />
</beans:bean>
<beans:bean id="customAuthenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<beans:property name="defaultTargetUrl" value="/home.htm" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureUrl" value="/login.jsp?authfailed=true" />
<beans:property name="allowSessionCreation" value="true" />
</beans:bean>
<global-method-security secured-annotations="disabled">
</global-method-security>
<beans:bean id="myAuthenticationEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp" />
</beans:bean>
<http entry-point-ref="myAuthenticationEntryPoint" auto-config="false">
<intercept-url pattern="/login.jsp" filters="none" />
<intercept-url pattern="/admin.htm" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<logout invalidate-session="true" logout-url="/logout.htm"
logout-success-url="/login.jsp?loggedout=true" />
<custom-filter position="FORM_LOGIN_FILTER"
ref="customAuthenticationProcessingFilter"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service id="userDetailsService">
<user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="username" password="password" authorities="ROLE_USER" />
<user name="test" password="test" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Regards,
Nazir
org.springframework.security.userdetails.UserDetailsService is from Spring Security 2.x, in Spring Security 3.x its name is org.springframework.security.core.userdetails.UserDetailsService.
So, you have some Spring Security 2.x jars in the classpath.
Could somebody help me with the "java.lang.IllegalArgumentException: No DataSource specified" issue while defining secured URLs dynamically against AppFuse 2.1 (with Spring Security 3.0.5 and iBatis)??
Before I started to define secured URLs dynamically, the following namespace in security.xml was working fine.
...
<http auto-config="false" lowercase-comparisons="false">
<intercept-url pattern="/images/**" filters="none"/>
<intercept-url pattern="/styles/**" filters="none"/>
<intercept-url pattern="/scripts/**" filters="none"/>
<intercept-url pattern="/app/admin/**" access="ROLE_ADMIN,ROLE_USER"/>
<intercept-url pattern="/app/passwordHint*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
<intercept-url pattern="/app/signup*" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/>
<intercept-url pattern="/app/**" access="ROLE_ADMIN,ROLE_USER"/>
<form-login login-page="/login" authentication-failure-url="/login?error=true" login-processing-url="/j_security_check"/>
<remember-me user-service-ref="userDao" key="e37f4b31-0c45-11dd-bd0b-0800200c9a66"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDao">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
...
But after I commented out the element and add the following elements in security.xml, the "userDao" did not work due to no datasource specified.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
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.0.xsd">
<beans:bean id="springSecurityFilterChain"
class="org.springframework.security.web.FilterChainProxy">
<filter-chain-map path-type="ant">
<filter-chain pattern="/images/**" filters="none"/>
<filter-chain pattern="/styles/**" filters="none"/>
<filter-chain pattern="/scripts/**" filters="none"/>
<filter-chain pattern="/app/**" filters="
securityContextPersistenceFilter,
logoutFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor"/>
</filter-chain-map>
</beans:bean>
<beans:bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
</beans:bean>
<beans:bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="/login"/>
<beans:constructor-arg ref="logoutHandler">
</beans:constructor-arg>
</beans:bean>
<beans:bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
</beans:bean>
<beans:bean id="authenticationProcessingFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="authenticationSuccessHandler"
ref="authenticationSuccessHandler"/>
<beans:property name="filterProcessesUrl" value="/j_security_check"/>
</beans:bean>
<beans:bean id="authenticationSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/app/mainMenu"/>
</beans:bean>
<beans:bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>
<beans:bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login"/>
</beans:bean>
<beans:bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/403.jsp"/>
</beans:bean>
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="securityMetadataSource" ref="myFilterInvocationSecurityMetadataSource"/>
</beans:bean>
<beans:bean id="myFilterInvocationSecurityMetadataSource"
class="com.tangram.ebiz.webapp.authentication.MyFilterInvocationSecurityMetadataSource">
</beans:bean>
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="ROLE_"/>
</beans:bean>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="userDao"
class="com.tangram.ebiz.dao.ibatis.UserDaoiBatis">
<beans:property name="sqlMapClient" ref="sqlMapClient"/>
</beans:bean>
<beans:bean id="sqlMapClient"
class="com.ibatis.sqlmap.engine.impl.SqlMapClientImpl">
<beans:constructor-arg ref="sqlMapExecutorDelegate"/>
</beans:bean>
<beans:bean id="sqlMapExecutorDelegate"
class="com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate">
</beans:bean>
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<beans:property name="url" value="jdbc:oracle:thin:#localhost:1521:XE"/>
<beans:property name="username" value="ebiz"/>
<beans:property name="password" value="ebiz"/>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
<beans:ref local="anonymousAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDao"/>
<beans:property name="passwordEncoder" ref="passwordEncoder"/>
</beans:bean>
<beans:bean id="anonymousAuthenticationProvider"
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<beans:property name="key" value="doesNotMatter"/>
</beans:bean>
<!-- Override the default password-encoder (SHA) by uncommenting the following and changing the class -->
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
<global-method-security>
<protect-pointcut expression="execution(* *..service.UserManager.getUsers(..))" access="ROLE_ADMIN"/>
<protect-pointcut expression="execution(* *..service.UserManager.removeUser(..))" access="ROLE_ADMIN"/>
</global-method-security>
</beans:beans>
If you are using a custom user service, you need to ref that:
<security:authentication-manager>
<security:authentication-provider user-service-ref="myUserDetailsService">
<security:password-encoder ref="md5" />
</security:authentication-provider>
</security:authentication-manager>
If you are using JDBC and just going against a set of tables, you just ref the datasource:
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="my-ds"/>
<security:password-encoder hash="md5"/>
</security:authentication-provider>
</security:authentication-manager>