package fr.ippon.tatami.security;
import com.google.inject.Inject;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.core.profile.UserProfile;
import org.pac4j.springframework.security.authentication.ClientAuthenticationToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
/**
*
*/
public class GoogleAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = LoggerFactory.getLogger(GoogleAuthenticationProvider.class);
// In our case, the only actual client is the google client
@Inject
private Clients clients;
// Get/Create new user
@Inject
private AuthenticationUserDetailsService<ClientAuthenticationToken> userDetailsService;
public GoogleAuthenticationProvider() {
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
logger.debug("authentication : {}", authentication);
if(!this.supports(authentication.getClass())) {
logger.debug("unsupported authentication class : {}", authentication.getClass());
return null;
} else {
ClientAuthenticationToken token = (ClientAuthenticationToken)authentication;
Credentials credentials = (Credentials)authentication.getCredentials();
logger.debug("credentials : {}", credentials);
String clientName = token.getClientName();
Client client = this.clients.findClient(clientName);
UserProfile userProfile = client.getUserProfile(credentials, (WebContext)null);
logger.debug("userProfile : {}", userProfile);
Object authorities = new ArrayList();
ClientAuthenticationToken result = null;
logger.debug("userDetailsService: {}", this.userDetailsService);
result = new ClientAuthenticationToken(credentials, clientName, userProfile, (Collection)null);
UserDetails userDetails = this.userDetailsService.loadUserDetails(result);
logger.debug("userDetails : {}", userDetails);
if(userDetails != null) {
authorities = userDetails.getAuthorities();
logger.debug("authorities : {}", authorities);
}
GoogleAuthenticationToken res = new GoogleAuthenticationToken(userDetails, clientName, (Collection)authorities);
logger.debug("Client name : {}", clientName); // -> Google2Client
logger.debug("Client Credentials: {}", credentials); // -> OAuth Credentials
logger.debug("Client Profile: {}", userProfile); // -> GoogleProfile, i.e. data from google
res.setDetails(authentication.getDetails());
logger.debug("result : {}", res);
return res;
}
}
public UserDetails createPrincipal() {
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return ClientAuthenticationToken.class.isAssignableFrom(authentication);
}
public void setUserDetailsService(AuthenticationUserDetailsService<ClientAuthenticationToken> userDetailsService) {
this.userDetailsService = userDetailsService;
}
public AuthenticationUserDetailsService<ClientAuthenticationToken> getUserDetailsService() {
return this.userDetailsService;
}
public void setClients(Clients clients) {
this.clients = clients;
}
public Clients getClients() {
return clients;
}
}