001/*
002 * Copyright (c) 2013 - 2016 TDP Ltd All Rights Reserved.
003 * TDP Ltd grants permission, free of charge, to any person obtaining copies
004 * of this software and its associated documentation files (the "Software"),
005 * to deal in the Software without restriction, including to use, copy, adapt,
006 * publish, distribute, display, perform, sublicense, and sell copies of the
007 * Software, subject to the following condition: You must include the above
008 * copyright notice and this permission notice in all full or partial copies
009 * of the Software.
010 * 
011 * TDP LTD PROVIDES THE SOFTWARE "AS IS," WITHOUT ANY EXPRESS OR IMPLIED WARRANTY,
012 * INCLUDING WITHOUT THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
013 * PARTICULAR PURPOSE, AND NON-INFRINGMENT. TDP LTD, THE AUTHORS OF THE SOFTWARE,
014 * AND THE OWNERS OF COPYRIGHT IN THE SOFTWARE ARE NOT LIABLE FOR ANY CLAIM, DAMAGES,
015 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING
016 * FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
017 * THE SOFTWARE.
018 */
019package cz.tdp.kshield.integration.web;
020
021import java.net.InetAddress;
022import java.net.UnknownHostException;
023
024import javax.servlet.http.HttpServletRequest;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.springframework.beans.factory.InitializingBean;
029
030import cz.tdp.kshield.client.UserInfo;
031import cz.tdp.kshield.integration.KShieldContext;
032import cz.tdp.kshield.integration.ServletAuthenticationService;
033import cz.tdp.kshield.integration.SimpleAuthenticationServiceImpl;
034
035/**
036 * Basic implementation of KeyShield SSO Server AuthenticationService.
037 * KShieldClient is used internally to communicate with KeyShield SSO Server.
038 * 
039 * @see cz.tdp.kshield.client.KShieldClient
040 */
041public class DefaultAuthenticationServiceImpl extends SimpleAuthenticationServiceImpl implements ServletAuthenticationService, InitializingBean
042{
043  /**
044   * @param url KeyShield SSO Server url
045   */
046  public DefaultAuthenticationServiceImpl(String url) {
047    super(url);
048  }
049  
050  @Override
051  public boolean authenticate(HttpServletRequest request) {
052    if (client == null) throw new IllegalStateException("This AuthenticaticationService must be initialized (method init) before attempt to authenticate");
053    
054    final String ipAddr = getClientIpAddress(request);
055    
056    if (ipAddr != null) {
057      final UserInfo userInfo = createUserInfo(ipAddr);
058      
059      if (userInfo != null && doAuthentication(request, userInfo)) {
060        // save principal in user session
061        request.getSession().setAttribute(KSHIELD_PRINCIPAL_TOKEN, userInfo);
062        return true;
063      }
064    }
065    
066    // close kshield session if authentication failed
067    KShieldContext.closeKShieldSession();
068    return false;
069  }
070
071  private String getClientIpAddress(HttpServletRequest request) {
072    try {
073      final InetAddress inetAddr = InetAddress.getByName(request.getRemoteAddr());
074      final String ipAddr = inetAddr.getHostAddress();
075      return ipAddr;
076    }
077    catch (UnknownHostException e) {
078      log.error("Cannot determine client ip address from remoteAddr: " + request.getRemoteAddr(), e);
079    }
080    
081    return null;
082  }
083  
084  /**
085   * Override this method to do real authentication steps
086   * 
087   * @param request current HTTP request
088   * @param userInfo User data returned by KeyShield SSO Server client
089   * @return true if user was sucessfully authenticated
090   */
091  protected boolean doAuthentication(HttpServletRequest request, UserInfo userInfo) {
092    // only check if userInfo is not null
093    return userInfo != null;
094  }
095  
096  /* (non-Javadoc)
097   * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
098   */
099  @Override
100  public void afterPropertiesSet() {
101    if (client == null) {
102      init();
103    }
104  }
105
106  private static final Log log = LogFactory.getLog(DefaultAuthenticationServiceImpl.class);
107}