package org.appfuse.webapp; import org.apache.wicket.authroles.authorization.strategies.role.Roles; import org.apache.wicket.injection.Injector; import org.apache.wicket.request.Request; import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; import org.apache.wicket.spring.injection.annot.SpringBean; import org.appfuse.model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.session.SessionRegistry; import java.util.ArrayList; import java.util.List; /** * AuthenticatedWebSession implementation using Spring Security. * * Based on: https://cwiki.apache.org/confluence/display/WICKET/Spring+Security+and+Wicket-auth-roles * * @author Marcin ZajÄ…czkowski, 2011-02-05 */ public class SSAuthenticatedWebSession extends AuthenticatedWebSession { protected final Logger log = LoggerFactory.getLogger(getClass()); @SpringBean(name = "authenticationManager") private AuthenticationManager authenticationManager; @SpringBean private SessionRegistry sessionRegistry; public SSAuthenticatedWebSession(Request request) { super(request); Injector.get().inject(this); if (authenticationManager == null) { throw new IllegalStateException("Injection of AuthenticationManager failed."); } } @Override public boolean authenticate(String username, String password) { boolean authenticated; try { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(username, password)); SecurityContextHolder.getContext().setAuthentication(authentication); //A hack to allow to track logged users without using SessionManagementFilter which is problematic in Wicket sessionRegistry.registerNewSession(getId(), authentication.getPrincipal()); authenticated = authentication.isAuthenticated(); } catch (AuthenticationException e) { log.warn("User '{}' failed to login. Reason: {}", username, e.getMessage()); authenticated = false; } return authenticated; } //FIXME: MZA: Modification of returning object - it would be better if roles were returned @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()); } } public List<User> getActiveUsers() { //RequestLogger is an alternative, but it keeps only session, not related principals List<Object> allPrincipals = sessionRegistry.getAllPrincipals(); List<User> users = new ArrayList<User>(allPrincipals.size()); for (Object principal : allPrincipals) { users.add((User)principal); } return users; } }