I use Fortify for scanning code and got this problem by recommend
Recommendations: Utilize Spring Security and SSL to provide authentication, authorization, confidentiality and integrity.
So I'm trying to fix this problem by implement Spring Security and basic authentication from the example guide
http://www.jayway.com/2008/09/30/spring-remoting-with-security-and-ssl/
I will get spring configuration like this
---- Server Side Configurations ---
remote-server.xml
<bean name="/testService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="testService" />
<property name="serviceInterface" value="example.TestService" />
</bean>
security-server.xml
<security:http auto-config="true">
<security:http-basic/>
<security:intercept-url pattern="/**" access="ROLE_ADMIN" />
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:user-service id="uds">
<security:user name="testUser" password="testPassword" authorities="ROLE_ADMIN, ROLE_MANAGER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
--- Client Side Configurations ---
remote-client.xml
<bean id="rcaRemotingService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="${endpoint.url}/testService"/>
<property name="serviceInterface" value="example.TestService"/>
<property name="username" value="${endpoint.user}"/>
<property name="password" value="${endpoint.password}"/>
</bean>
But it doesn't work, the tools always hilight the problem like this
Abstract: On line 5 of remoting-servlet.xml, the application exposes
spring beans as remote services. By default, these remote services do
not require authentication and information transferred to or from this
service is in clear text. This could allow an attacker to access
privileged operations or expose sensitive data.
Sink: remote-server.xml:5 null()
line 5: <bean name="/testService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="testService" />
<property name="serviceInterface" value="example.TestService" />
</bean>
Related
I am learning and need to configure siteminder SSO with Spring Security. I followed some blog and wrote my code as fllowing. Plz help to resolove: "No bean named 'springSecurityFilterChain' is defined" error. Here is my code:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/conf/Security-config.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Security-config.xml
<security:http use-expressions="true" auto-config="false" entry-point-ref="http403EntryPoint">
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</security:http>
<bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<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="customUserDetailsService"/>
</bean>
</property>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>
<bean id="customUserDetailsService" class="com.cno.cnofdw.security.CustomUserDetailsService"></bean>
<bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"></bean>
Placed Security-config.xml under WEB-INF/conf/
Even I tried importing in applicationContext.xml. but no use.
Can anybody help me to resolve this problem and if possible please suggest any blog to configure spring with siteminder signle sign on?
Your missing "/" in path. It should be:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/conf/Security-config.xml
</param-value>
</context-param>
thank you all who spent time to answer my question. I have placed contextClass in my web.xml and I have commented it and got resolved.
contextClass
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
My Spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- This is where we configure Spring-Security -->
<security:global-method-security pre-post-annotations="enabled" />
<!-- <security:global-method-security secured-annotations="enabled" /> -->
<security:http auto-config="false" use-expressions="true" access-denied-page="/access-deniad"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/RetailEnterpriseSuite/login.do" access="permitAll" requires-channel="https" />
<security:intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" requires-channel="https"/>
<!-- <security:intercept-url pattern="/common" access="hasRole('ROLE_USER')"/> -->
<security:intercept-url pattern="/users" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/*" access="permitAll" requires-channel="any"/>
<security:logout
invalidate-session="true"
logout-success-url="/login.html"
logout-url=""/>
<!--
Querying the SessionRegistry for currently authenticated users and their sessions
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/session-mgmt.html#list-authenticated-principals
-->
<security:custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER"/>
<security:custom-filter ref="singleEntryFilter" after="FORM_LOGIN_FILTER"/>
<security:session-management session-authentication-strategy-ref="sas"/>
</security:http>
<bean id="singleEntryFilter" class="com.stc.res.filter.SingleEntryFilter"
p:redirectURI="/login.html">
<property name="guardURI">
<list>
<!-- <value>/index.html</value> -->
<value>/index.html</value>
<!-- <value>/index.html</value>
<value>/index.html</value>
<value>/index.html</value>
<value>/index.html</value> -->
</list>
</property>
</bean>
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
p:sessionAuthenticationStrategy-ref="sas"
p:authenticationManager-ref="authenticationManager"
p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler"/>
<!-- We just actually need to set the default failure url here -->
<bean id="customAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
p:defaultFailureUrl="/loginfailed" />
<!-- We just actually need to set the default target url here -->
<bean id= "customAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="redirectStrategy" ref="customSuccessRedirStrategy" />
</bean>
<!-- <bean id="customAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
p:redirectStrategy-ref="customSuccessRedirStrategy" /> -->
<bean id= "customSuccessRedirStrategy" class=" com.stc.res.customeredirection.CustomSuccessRedirection"> </bean>
<!-- The AuthenticationEntryPoint is responsible for redirecting the user to a particular page, like a login page,
whenever the server sends back a response requiring authentication -->
<!-- See Spring-Security Reference 5.4.1 for more info -->
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
p:loginFormUrl="/login.html"/>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<!-- It's important to set the alias here because it's used by the authenticationFilter -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userservice">
<security:password-encoder ref="passwordEncoder">
<security:salt-source ref="saltSource"/>
</security:password-encoder>
</security:authentication-provider>
<security:authentication-provider user-service-ref="jdbcUserService"/>
</security:authentication-manager>
<bean id="userservice" class="com.stc.res.service.UserLoginService" >
<property name="usrlogindao" ref="userLogindao"/>
</bean>
<bean id="userLogindao" class = "com.stc.res.dao.UserLoginDao" />
<bean id="jdbcUserService" class="com.stc.res.service.JdbcUserService">
<property name="customJdbcDao" ref="custjdbcDao"/>
</bean>
<bean id="custjdbcDao" class= "com.stc.res.dao.CustomJdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="jdbcAdminUserService" class="com.stc.res.controller.JdbcAdminUserService">
<property name="dataSource" ref="dataSource"/>
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<!-- Use a Sha encoder since the user's passwords are stored as Md5 in the database -->
<bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder"/>
<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
<property name="userPropertyToUse" value="username"/>
</bean>
<!-- <security:bean id="rememberMeServices" class="org.springframework.security.ui.rememberme.PersistentTokenBasedRememberMeServices">
<property name="tokenRepository" ref="jdbcTokenRepository" />
<property name="userDetailsService" ref="userservice" />
<property name="key" value="springRocks" />
<property name="alwaysRemember" value="false" />
</security:bean>
Uses a database table to maintain a set of persistent login data
<security:bean id="jdbcTokenRepository" class="org.springframework.security.ui.rememberme.JdbcTokenRepositoryImpl">
<property name="createTableOnStartup" value="false" />
<property name="dataSource" ref="dataSource" />
</security:bean>
-->
<!-- An in-memory list of users. No need to access an external database layer.
See Spring Security 3.1 Reference 5.2.1 In-Memory Authentication -->
<!-- john's password is admin, while jane;s password is user -->
<!-- Filter required by concurrent session handling package
The ConcurrentSessionFilter requires two properties, sessionRegistry, which generally points to an
instance of SessionRegistryImpl, and expiredUrl, which points to the page to display when a session has expired.
See: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/session-mgmt.html#list-authenticated-principals -->
<bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter"
p:sessionRegistry-ref="sessionRegistry"
p:expiredUrl="/login.html" />
<!-- Defines a concrete concurrent control strategy
Checks whether the user in question should be allowed to proceed, by comparing the number of
sessions they already have active with the configured maximumSessions value. The SessionRegistry
is used as the source of data on authenticated users and session data.
See: http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/authentication/session/ConcurrentSessionControlStrategy.html-->
<bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy"
p:maximumSessions="1" error-if-maximum-exceeded="true" >
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
</bean>
<!-- Maintains a registry of SessionInformation instances
See: http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/core/session/SessionRegistry.html -->
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
</beans>
and I configured the in web.xml:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<display-name>MycustomFilter</display-name>
<filter-name>MycustomFilter</filter-name>
<filter-class>com.stc.res.filter.MycustomFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MycustomFilter</filter-name>
<url-pattern>/MycustomFilter</url-pattern>
</filter-mapping>
listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
Please let me know where is the fault in this code, and please guide me. I am new to spring-security. Even user can login from different browser, without logging out.
Have you tried this snippet from the official documentation (preventing multiple logins):
<security:http ... >
....
<security:session-management>
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>
</security:http>
Does anybody have the Spring Security sample PreAuthentication Filter for WebSphere working (WebSpherePreAuthenticatedProcessingFilter)? There is very little documentation on it and I just can't seem to nail it. I'm looking for someone who has it working and might be willing to provide examples of your configuration. Ideally for Spring 3.1 and WAS 7 or 8.
I have a configuration in place that seems like it's "kind of" working. I can authenticate with WebSphere and then hit a URL in my app, but the browser returns this message:
Error 500: java.lang.RuntimeException: Exception occured while looking up groups for user
I get an exception stack trace like this:
java.lang.RuntimeException: Error while invoking method java.lang.reflect.Method.getGroupsForUser([UNAUTHENTICATED])
at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.invokeMethod(DefaultWASUsernameAndGroupsExtractor.java:147) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:115) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(
...
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) ~[na:1.6.0]
...
Caused by: com.ibm.websphere.security.EntryNotFoundException: null
at com.ibm.ws.wim.registry.util.MembershipBridge.getGroupsForUser(MembershipBridge.java:293) ~[com.ibm.ws.runtime.wim.core.jar:201207200704]
...
[12/28/12 14:05:15:879 CST] 00000055 LocalTranCoor E WLTC0017E: Resources rolled back due to setRollbackOnly() being called.
[12/28/12 14:05:15:879 CST] 00000055 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[ServletNameNotFound]: java.lang.RuntimeException: Exception occured while looking up groups for user
at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:123)
at org.springframework.security.web.authentication.preauth.websphere.DefaultWASUsernameAndGroupsExtractor.getWebSphereGroups(DefaultWASUsernameAndGroupsExtractor.java:94)
...
My web.xml file is as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext-jcr.xml,
classpath*:/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!--
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
-->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- ====================================================================== -->
<!-- S E R V L E T S -->
<!-- ====================================================================== -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ViewStatusMessages</servlet-name>
<servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>
<!-- ====================================================================== -->
<!-- S E R V L E T M A P P I N G S -->
<!-- ====================================================================== -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ViewStatusMessages</servlet-name>
<url-pattern>/lbClassicStatus</url-pattern>
</servlet-mapping>
<!-- ====================================================================== -->
<!-- W E L C O M E F I L E S -->
<!-- ====================================================================== -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Use if configuring for JNDI Datasource on J2EE Server -->
<resource-ref id="ResourceRef_LDP_Datasource">
<description>Resource reference to the LDP datasource.</description>
<!-- DB2 -->
<res-ref-name>jdbc/ldpdbDS</res-ref-name>
<!-- MS SQL -->
<!--
<res-ref-name>jdbc/ldpdbMSSQLDS</res-ref-name>
-->
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<!--
security-constraint reference:
http://s170.codeinspot.com/q/3419721
OK, I figured this out. The problem is that even though I had J2EE security setup in Websphere and was authenticated,
my web.xml contained no security constraints. Because of this, Websphere was not supplying the principal for my requests.
This is apparently an intentional feature. If you are not accessing a protected URL, you should not need the pre-authentication information.
To overcome this, I added a security constraint to my web.xml, which allowed ALL users to access the resources.
Effectively, the resources were not secured, but still - there was a constraint now.
This tricks the Websphere into filling in the user principal information in the request.
-->
<security-constraint>
<web-resource-collection>
<web-resource-name>All areas</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
My Spring security context XML file is as follows:
<!--
<sec:http use-expressions="true">
<sec:intercept-url pattern="/**" access="denyAll" />
<sec:form-login />
</sec:http>
-->
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<!--
<sec:filter-chain pattern="/**" filters="sif,webspherePreAuthFilter,logoutFilter,etf,fsi"/>
-->
<sec:filter-chain pattern="/**" filters="webspherePreAuthFilter,logoutFilter,etf,fsi"/>
</sec:filter-chain-map>
</bean>
<!--
<bean id="sif" class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
<bean id="sif" class="org.springframework.security.web.context.SecurityContextIntegrationFilter"/>
-->
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="preAuthenticatedAuthenticationProvider"/>
</sec:authentication-manager>
<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
</bean>
<bean id="preAuthenticatedUserDetailsService" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService"/>
<!--
This AbstractPreAuthenticatedProcessingFilter implementation is based on WebSphere authentication.
It will use the WebSphere RunAs user principal name as the pre-authenticated principal.
-->
<bean id="webspherePreAuthFilter" class="org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
</bean>
<bean id="preAuthenticatedProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<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>
<!--
This AuthenticationDetailsSource implementation will set the pre-authenticated granted authorities based on the WebSphere
groups for the current WebSphere user, mapped using the configured Attributes2GrantedAuthoritiesMapper.
This AuthenticationDetailsSource implementation, when configured with a MutableGrantedAuthoritiesContainer,
will set the pre-authenticated granted authorities based on the WebSphere groups for the current WebSphere user,
mapped using the configured Attributes2GrantedAuthoritiesMapper.
By default, this class is configured to build instances of the PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails class.
-->
<bean id="authenticationDetailsSource" class="org.springframework.security.web.authentication.preauth.websphere.WebSpherePreAuthenticatedWebAuthenticationDetailsSource">
<property name="webSphereGroups2GrantedAuthoritiesMapper" ref="websphereUserGroups2GrantedAuthoritiesMapper"/>
</bean>
<bean id="websphereUserGroups2GrantedAuthoritiesMapper" class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
<property name="convertAttributeToUpperCase" value="true"/>
</bean>
<bean id="webXmlResource" class="org.springframework.web.context.support.ServletContextResource">
<constructor-arg ref="servletContext"/>
<constructor-arg value="/WEB-INF/web.xml"/>
</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="preAuthenticatedProcessingFilterEntryPoint"/>
</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>
<!-- See: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-web-filters.html -->
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/**" access="ROLE_LDP_ADMINS"/>
</sec:filter-security-metadata-source>
</property>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<!--
Simply put, the filter wraps the current httprequest with one that delegates request.isUserInRole() and request.getRemoteUser() to acegi.
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
<property name="wrapperClass" value="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper"/>
</bean>
-->
I don't have a working config but a piece of advice
enable Spring Security debug logging
debug as closely as possibly into MembershipBridge.getGroupsForUser, I have a feeling the username passed to it is null
Based on my gut feeling I suspect the name of the pre-authenticated user is not being passed on. I remember vaguely that I had this a few years ago - need to dig up that code.
For some reason WebSphere doesn't require authentication for resources with the following constraint definition and the pre-authentication doesn't happen:
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
It fails in the later stage when it tries to determine groups for an unknown principal.
I protected the resource with a default group Users and mapped all users to it:
<security-constraint>
<web-resource-collection>
<web-resource-name>AuthTest</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>User</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>User</role-name>
</security-role>
It is sort of a workaround because I don't want this role and manage its members but it is all I have for now.
My application's sequrity system is based on Spring Sequrity 3.1. I am using PersistentTokenBasedRememberMeServices.
I need to display a list of all logged users using Sessionregistrympl. The problem is that when the site goes "rememberme-user", it's session does not exist in SessionRegistry.
My configuration files:web.xml
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
and spring-sequrity.xml:
<s:http auto-config="false" entry-point-ref="authenticationEntryPoint" >
<s:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter"/>
<s:custom-filter position="REMEMBER_ME_FILTER" ref="rememberMeFilter" />
<s:custom-filter position="CONCURRENT_SESSION_FILTER" ref= "concurrencyFilter" />
<s:custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
<s:intercept-url pattern="/admin/**/" access="ROLE_ADMIN"/>
<s:intercept-url pattern="/**/" access="ROLE_USER, ROLE_GUEST"/>
<s:anonymous username="guest" granted-authority="ROLE_GUEST" />
</s:http>
<bean
id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter"
p:filterProcessesUrl="/logout/">
<constructor-arg value="/login/" />
<constructor-arg>
<list>
<ref bean="rememberMeServices" />
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" p:invalidateHttpSession="true"/>
</list>
</constructor-arg>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
p:loginFormUrl="/login/"/>
<bean id="customAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
p:defaultTargetUrl="/index/" />
<bean id="customAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
p:defaultFailureUrl="/login/error/" />
<bean id="rememberMeServices"
class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices"
p:tokenRepository-ref="jdbcTokenRepository"
p:userDetailsService-ref="hibernateUserService"
p:key="pokeristStore"
p:tokenValiditySeconds="1209600" />
<bean id="jdbcTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"
p:dataSource-ref="dataSource"/>
<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider"
p:key="pokeristStore" />
<bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter"
p:rememberMeServices-ref="rememberMeServices"
p:authenticationManager-ref="authenticationManager" />
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
p:sessionAuthenticationStrategy-ref="sas"
p:authenticationManager-ref="authenticationManager"
p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
p:rememberMeServices-ref="rememberMeServices"
p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler"/>
<bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy"
p:maximumSessions="1">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
</bean>
<bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter"
p:sessionRegistry-ref="sessionRegistry" />
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256"/>
</bean>
<bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="username"/>
</bean>
<bean id="hibernateUserService"
class="com.mysite.service.simple.SecurityUserDetailsService"/>
<s:authentication-manager alias="authenticationManager">
<s:authentication-provider user-service-ref="hibernateUserService">
<s:password-encoder ref="passwordEncoder">
<s:salt-source ref="saltSource"/>
</s:password-encoder>
</s:authentication-provider>
<s:authentication-provider ref="rememberMeAuthenticationProvider" />
How can I solve this problem?
One of the solutions found by me - is to set alwaysReauthenticate property to 'true' in FilterSecurityInterceptor bean, but it affects the performance of web-site.
You need a ConcurrentSessionControlStrategy, to populate the session registry. This is described in the session management section of the manual. Check out the configuration example in there if you want to use plain Spring beans. Note that you need to inject it into both the supply the same reference to both the UsernamePasswordAuthenticationFilter and the session-management namespace element.
If you want SessionRegistry to be populated Spring Security have to create a session, try adding create-session="always" to your <http> tag in Spring Security configuration file.
I have configured my web application with the following config file:
<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.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />
<!--
Filter chain; this is referred to from the web.xml file. Each filter
is defined and configured as a bean later on.
-->
<!-- Note: anonumousProcessingFilter removed. -->
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter,
basicAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<!--
This filter is responsible for session management, or rather the lack
thereof.
-->
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository">
<bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
<property name="allowSessionCreation" value="false" />
</bean>
</property>
</bean>
<!-- Basic authentication filter. -->
<bean id="basicAuthenticationFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
</bean>
<!-- Basic authentication entry point. -->
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="Ayudo Web Service" />
</bean>
<!--
An anonymous authentication filter, which is chained after the normal authentication mechanisms and automatically adds an
AnonymousAuthenticationToken to the SecurityContextHolder if there is no existing Authentication held there.
-->
<!--
<bean id="anonymousProcessingFilter" class="org.springframework.security.web.authentication.AnonymousProcessingFilter">
<property name="key" value="ayudo" /> <property name="userAttribute" value="anonymousUser, ROLE_ANONYMOUS" /> </bean>
-->
<!--
Authentication manager that chains our main authentication provider
and anonymous authentication provider.
-->
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" />
<ref local="inMemoryAuthenticationProvider" />
<!-- <ref local="anonymousAuthenticationProvider" /> -->
</list>
</property>
</bean>
<!--
Main authentication provider; in this case, memory implementation.
-->
<bean id="inMemoryAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="propertiesUserDetails" />
</bean>
<security:user-service id="propertiesUserDetails" properties="classpath:operators.properties" />
<!-- Main authentication provider. -->
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<!--
An anonymous authentication provider which is chained into the ProviderManager so that AnonymousAuthenticationTokens are
accepted.
-->
<!--
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="ayudo" /> </bean>
-->
<bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
<property name="accessDeniedHandler">
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl" />
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<security:filter-security-metadata-source use-expressions="true">
<security:intercept-url pattern="/*.html" access="permitAll" />
<security:intercept-url pattern="/version" access="permitAll" />
<security:intercept-url pattern="/users/activate" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
<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.web.access.expression.WebExpressionVoter" />
</list>
</property>
</bean>
As soon as I run my application on tomcat, I get a request for username/password basic authentication dialog. Even when I try to access: localhost:8080/myapp/version, which is explicitly set to permitAll, I get the authentication request dialog. Help!
Thank,
Sammy
You have the basicAuthenticationFilter in your filter chain therefor it's going to try to authenticate a user. The permitAll will allow any user, but the request still needs to have a user in the SecurityContext (retrieved from your UserDetailsService).
If you want those URI's to allow all access (even without authenticating a user) then do this:
<intercept-url pattern="/version" filters="none"/>