I'm trying to add <session-management> in my Spring Security namespace configuration so that I can provide a different message than the login page when the session times out. As soon as I add it to my configuration it starts throwing "IllegalStateException: Cannot create a session after the response has been committed" when I access the app.
I'm using Spring Security 3 and Tomcat 6. Here's my configuration:
<http>
<intercept-url pattern="/go.htm" access="ROLE_RESPONDENT" />
<intercept-url pattern="/complete.htm" access="ROLE_RESPONDENT" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-processing-url="/j_spring_security_check"
login-page="/login.htm"
authentication-failure-url="/login.htm?error=true"
default-target-url="/go.htm"
/>
<anonymous/>
<logout logout-success-url="/logout_message.htm"/>
<session-management invalid-session-url="/login.htm" />
</http>
Everything works great until I add in the <session-management> line. What am I missing?
You are probably hitting this bug:
https://jira.springsource.org/browse/SEC-1346
Try using the up-to-date version (3.0.2.RELEASE).
This works for me
<session-management invalid-session-url="/taac/login">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
Maybe including the auto-config="true" attribute in the <http> tag helps, you might be missing some required filters or settings.
Related
I'm using spring security to authenticate users, if it's the right user :he has access to the home page ..
But when I tried to enter with the url (without entering my name or my password ) an anonymous user can see the home page !
My application is not secured !
Could someone help me please ?
This is my spring-securityConfig.xml :
<http auto-config="true">
<form-login login-page="/login" username-parameter="j_username"
password-parameter="j_password" default-target-url="/accueil"
authentication-failure-url="/403" always-use-default-target="true" />
<logout logout-success-url="/login" />
<http-basic/>
<intercept-url pattern="/**" />
</http>
<authentication-manager>
<authentication-provider ref="userService">
</authentication-provider>
</authentication-manager>
You don't have to do anything for the redirection, it comes with Spring Security by default. It's just that your home page isn't secure. Did you try
<intercept-url pattern="/login*" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
The title of the question speaks for itself.
I want both to secure home.xhtml and the clean URL /Home.
In spring security config, do i need to do what follows or is there another way of doing it ?
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/home.xhtml" access="isAuthenticated()" />
<security:intercept-url pattern="/Home" access="isAuthenticated()" />
</security:http>
Thanks
UPDATE :
Actually my solution is to be careful with files and url names.I do this in spring security file to be more coherent:
<security:intercept-url pattern="/Home*" access="isAuthenticated()" />
That secures the two URL...all url in fact beginning by Home (not case sensitive)
I am new to wicket and SpringSecurity. I configured the spring security as follows.
<http create-session="never" auto-config="true">
<remember-me />
<http-basic />
<intercept-url pattern="/**" requires-channel="https" />
<!-- <form-login login-page="/admin"/> <logout invalidate-session="true"
logout-url="/j_spring_security_logout" logout-success-url="/admin" delete-cookies="JSESSIONID"/> -->
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</session-management>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService"></authentication-provider>
</authentication-manager>
<global-method-security secured-annotations="enabled" />
I have extended the AuthenticatedWebSession doing the authentication in my extended class.
My Questions :
How can I configure for form based Authentication.
How can I configure for Session Management.
How can I configure for Single Sign in per user (Here if the user try to login with same user I want invalidate the session of the previous logged in user. )
Need reference manual on Spring Security Integration with Wicket.
Please also let me know if I am missing anything.
you can have a look at the following working example on Wicket / Spring-Security integration on github: https://github.com/thombergs/wicket-spring-security-example.
Your questions are a little vague for a helpful answer, so I'd suggest yoiu have a look at the example on github and ask again if you have any problems.
Regards,
Tom
strange one,
I am using spring security with siteminder and it works fine. However I want to have one url which isn't protected - our loadBalancer needs a "healthCheck" url within the app itself. This url isn't intercepted by siteminder, but spring security seems to apply the preauth to it anyhow..
if I run it locally using a simple forms-based security config the following works (excluding the filters):
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/html/healthCheck.html" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/login" filters="none" />
<intercept-url pattern="/favicon.ico" filters="none" />
<intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
<form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
In this case, I can browse to localhost/myApp/resources/html/healthCheck.html without hitting an authorization issue, but any other url will display the login form. All looking good so far!
However when I deploy to the server I am using the following config:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/html/healthCheck.html" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/login" filters="none" />
<intercept-url pattern="/favicon.ico" filters="none" />
<intercept-url pattern="/*" access="hasAnyRole('ROLE_USER')" />
<custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>
When I browse to: server/myapp/resources/html/healthCheck.html I get the following error:
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
org.springframework.security.core.userdetails.User.<init>(User.java:94)
com.myApp.security.SecuritySBSUserDetailsService.loadUserByUsername(SecuritySBSUserDetailsService.java:119)
org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper.loadUserDetails(UserDetailsByNameServiceWrapper.java:53)
I think this is caused by the UserDetailsService getting instantiated without any SM_USER. Yet the filters=none is in place.. and works when using forms authentication..Any idea what might be causing this, or better - of a workaround?
By the way, my userdetails service is configured as follows:
<beans:bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<beans:property name="principalRequestHeader" value="SM_USER" />
<beans:property name="exceptionIfHeaderMissing" value="false" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
i.e. I've set exceptionIfHeaderMissing to false, if that helps..
The most obvious thing I can see is that /resources/html/healthCheck.html won't be matched by /html/healthCheck.html. If you are rewriting the URLs somewhere you should probably explain that.
If you enable debug logging, it should explain in detail what is matched against what.
I'd also leave out the auto-config. It causes more confusion than it is worth. And you should use /** rather than /* for a universal ant pattern match.
It's probably also worth mentioning here that Spring Security 3.1 has a better approach for defining empty filter chains, and also allows you to define more than one filter chain using the <http> syntax.
Okay, it seems to be a bug in spring security as far as I can see. I got around it by adding a dummy return to the start of the loadUserByName method in the UserDetailsService..
#Override
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException, DataAccessException {
logger.trace(">> loadUserByUsername()");
logger.info("-- loadUserByUsername(): username : {}", userName);
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
if(userName==null || userName.trim().equals("")) {
return(new User("ANONYMOUS", "", true, true, true, true, authorities));
}
// rest of auth checks
It would seem like with the config I have, the UserDetails check shouldn't be getting triggered at all (as it is with the forms..). If anyone has a configuration based workaround I'll give you a plus :-)
If I keep remember-me element in security.xml file and startup a server then I got following error.
No UserDetailsService registered.......
If I remove this remember-me element then it works fine.
How to get rid of this error...
<?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"
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">
<http auto-config="false" use-expressions="true"
access-denied-page="/login.jsp?error=true" entry-point-ref="authenticationEntryPoint">
<remember-me key="abcdefgh" />
<logout invalidate-session="true" />
<intercept-url pattern="/login.jsp" access="permitAll" />
<intercept-url pattern="/index.jsp" access="permitAll" />
<intercept-url pattern="/pub" access="isAuthenticated()" />
<intercept-url pattern="/*" access="permitAll" />
<custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER" />
</http>
<beans:bean id="authenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
p:authenticationManager-ref="customAuthenticationManager"
p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler" />
<!-- Custom authentication manager. In order to authenticate, username and
password must not be the same -->
<beans:bean id="customAuthenticationManager" class="com.cv.pub.cmgt.framework.security.CustomAuthenticationManager" />
<!-- We just actually need to set the default failure url here -->
<beans:bean id="customAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
p:defaultFailureUrl="/login.jsp?error=true" />
<!-- We just actually need to set the default target url here -->
<beans:bean id="customAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
p:defaultTargetUrl="/pub" />
<!-- 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 -->
<beans:bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
p:loginFormUrl="/login.jsp" />
<!-- The tag below has no use but Spring Security needs it to autowire the
parent property of org.springframework.security.authentication.ProviderManager.
Otherwise we get an error A probable bug. This is still under investigation -->
<authentication-manager />
</beans:beans>
Spring Security's provided RememberMeServices requires a UserDetailsService in order to work. This means you have two options:
1) If possible, I recommend this as your best option. Instead of writing a custom AuthenticationProvider, write a custom UserDetailsService. You can find an example UserDetailsService looking at InMemoryDaoImpl You can then wire it similar to the configuration below. Note you would remove your custom AuthenticationManager too.
<http ..>
...
<remember-me key="abcdefgh" />
</http>
<authentication-manager>
<authentication-provider user-service-ref="myUserService"/>
</authentication-manager>
<beans:bean id="myUserService" class="MyUserService"/>
2) Write your own RememberMeServices implementation that does not require a UserDetailsService. You can take a look at TokenBasedRememberMeServices for an example (but it requires UserDetailsService). If you want to use the namespace configuration your RememberMeServices implementation will need to implement LogoutHandler. You can then use the namespace to wire it.
<http ..>
...
<remember-me ref="myRememberMeServices"/>
</http>
<beans:bean id="myRememberMeServices" class="sample.MyRememberMeServices"/>