spring securit3.x y integration with wicket 6.7.0 - spring-security

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

Related

How to redirect user to authentication page when he tries to enter the url of the secured page ?

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()" />

Spring Security Preauth "filters=none" not working

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

Handling both form and HTTP basic authentication with different sources

I already have form login and Basic auth working side by side with the help of a DelegatingAuthenticationEntryPoint.
What I'm trying to do is have users coming thru the login form to be authenticated against criteria "A", and have users coming thru the Basic auth requests to be authenticated against criteria "B".
Some of the application's resources are exposed thru a RESTful service (accessible via Basic auth). Instead of having users enter their own credentials to make a REST service call, they can enter generated key/value pairs for use exclusively with the REST service that can later be revoked by the user or by the app administrator.
I would prefer to share as much of my security-specific beans as possible between the two methods of authentication. I know I will need separate UserDetailsServices as the form login queries my users table, and Basic auth will query my service_credentials table.
What is the correct way to achieve this kind of configuration in Spring Security?
Depending on your app and whether you're using Spring Security 3.1, you might be best to split the configuration into multiple filter chains, each with a separate authentication manager defined:
<http pattern="/rest_api/**" create-session="stateless"
authentication-manager-ref="serviceCredsAuthMgr">
<http-basic />
</http>
<http authentication-manager-ref="mainAuthMgr">
<form-login />
</http>
<authentication-manager id="serviceCredsAuthMgr">
<authentication-provider user-service-ref="serviceCredsUserDetailsSvc" />
</authentication-manager>
<authentication-manager id="mainAuthMgr">
<!-- whatever -->
</authentication-manager>
Instead of the pattern attribute you can also use the request-matcher-ref attribute to specify a RequestMatcher instance which will be used to map incoming requests to a particular filter chain. This has a very simple interface, but can allow you to match based on something other than the URL path, such as the Accept header.
With SpringSecurity (3.2.3.RELEASE) work fine form as well as basic auth:
<http pattern="/resources/**" security="none"/>
<http pattern="/webjars/**" security="none"/>
<http pattern="/rest/**" create-session="stateless" use-expressions="true">
<intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<http-basic />
</http>
<http auto-config="true" use-expressions="true">
<http-basic/>
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/loginfailed" access="permitAll"/>
<intercept-url pattern="/logout" access="permitAll"/>
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed"/>
<logout logout-success-url="/logout"/>
<remember-me user-service-ref="userService"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="userService">
<!--
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT email, password, enabled FROM users WHERE email = ?"
authorities-by-username-query="
SELECT u.email, r.name FROM users u, roles r WHERE u.id = r.user_id and u.email = ?"/>
-->
<!--
<user-service>
<user name="mail#yandex.ru" password="password" authorities="ROLE_USER"/>
<user name="admin#gmail.com" password="admin" authorities="ROLE_ADMIN"/>
</user-service>
-->
</authentication-provider>
</authentication-manager>

Spring Security Config Error while server startup

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"/>

Spring Security session-management setting and IllegalStateException

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.

Resources