In an older post I spoke about integrating Spring Security 3 with Extjs (here), now I will speak about integrating Spring Security 3 with Wicket.
Tools:
- Wicket 1.4.15
- Maven 3.0.2
- Spring Security 3.0.5
- IDE: Netbeans 6.9.1
- Server: Tomcat VI
How to start?
Just create a simple wicket application with maven and add the following dependencies for the Spring framework:
After that you should add the following code in web.xml:
Tools:
- Wicket 1.4.15
- Maven 3.0.2
- Spring Security 3.0.5
- IDE: Netbeans 6.9.1
- Server: Tomcat VI
How to start?
Just create a simple wicket application with maven and add the following dependencies for the Spring framework:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
<type>jar</type>
</dependency>
The wicket application class should extends AuthenticatedWebApplication.After that you should add the following code in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
The Spring XML configuration file:
<http create-session="never" auto-config="true" >
<remember-me/>
<intercept-url pattern="/**"/>
</http>
<!--
Usernames/Passwords are
moez/moez
test/test
-->
<authentication-manager alias="authenticationManager" >
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="moez" password="f69471ca2c42621b8b8e731b2b4446e4" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
<user name="test" password="098f6bcd4621d373cade4e832627b4f6" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<global-method-security secured-annotations="enabled" />
</beans:beans>
The authenticated websession:
public class SpringWicketWebSession extends AuthenticatedWebSession {
private static final Logger logger = Logger.getLogger(SpringWicketWebSession.class);
@SpringBean(name = "authenticationManager")
private AuthenticationManager authenticationManager;
public SpringWicketWebSession(Request request) {
super(request);
injectDependencies();
ensureDependenciesNotNull();
}
public static SpringWicketWebSession getSpringWicketWebSession() {
return (SpringWicketWebSession) Session.get();
}
private void ensureDependenciesNotNull() {
if (authenticationManager == null) {
throw new IllegalStateException("Requires an authentication");
}
}
private void injectDependencies() {
InjectorHolder.getInjector().inject(this);
}
@Override
public boolean authenticate(String username, String password) {
boolean authenticated = false;
try {
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
SecurityContextHolder.getContext().setAuthentication(authentication);
authenticated = authentication.isAuthenticated();
} catch (AuthenticationException e) {
logger.warn("User "+username+" failed to login. Reason: ", e);
authenticated = false;
}
return authenticated;
}
@Override
public Roles getRoles() {
Roles roles = new Roles();
getRolesIfSignedIn(roles);
return roles;
}
private void getRolesIfSignedIn(Roles roles) {
if (isSignedIn()) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
addRolesFromAuthentication(roles, authentication);
}
}
private void addRolesFromAuthentication(Roles roles, Authentication authentication) {
for (GrantedAuthority authority : authentication.getAuthorities()) {
roles.add(authority.getAuthority());
}
}
}
source code here
Thanks for the write up. You are more or less doing the same thing as described in the Wicket / Spring Security 3 Wiki.
ReplyDeleteThere is one difference - in SpringWicketWebSession you have a getSpringWicketWebSession() method. Is this necessary? Where is it used?
I am having a problem (I posted on the mailing list) where a line in the getRolesIfSignedIn() method is failing:
SecurityContextHolder.getContext().getAuthentication()
It sometimes returns null. Any idea why this might be happening? I am at a loss. It is almost completely random but seems to happen more after loading a page with a Panel in it. But not always.
I only need to put the @AuthorizeInstantiation tag in the Pages, correct? Not in the Forms or Panels contained within the Pages.
I have been trying to get this working for over a day. And help much appreciated.
Thanks,
Bob
Solved.
ReplyDeleteSee this thread.
It seems you need a Spring filter, *before* the Wicket filter.
Bob
No, it's ok for me. You can try with my web.xml
ReplyDeleteWell it's ok with you because you only have one page. My Login page worked fine as well, as did many Links. But eventually, once you start really navigating, loading Pages with Forms and Panels, it's only a matter of time before a npi shows up.
ReplyDeleteI was using exactly your web.xml and had this problem. Sticking a Spring filter in the mix fixed it. Fyi.
Cheers,
Bob
I added another page SuccessPage and always it's ok.
ReplyDeleteI posted the new code.
Well, as I said, for me it worked for all Links to all Pages. The problems started happening once I had Forms and Panels.
ReplyDeleteAnd it didn't always happen, it was completely random. The only real way to test it would be to make a page with a Form, and when you click on submit show a List of 'things' (Users, whatever) in a Panel, and click on one of those 'things' to see its details.
if *that* all works consistently, after clicking many times, then I'd be convinced. But I am pretty sure it will fail.
If not ... well, I have no idea why, but you're a lucky man!
Bob
Thanks for this post. I was experiencing the same intermittent problem as @syg6 and the filter ordering fixed the problem.
ReplyDeleteHi folks,
ReplyDeletehas anybody got the remember-me feature to work? does it require aditional code? from my logs i can see that the server never sets a cookie when i log in.
Any help appreciated.
Oliver