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.springsecurity3;
020
021import javax.servlet.http.HttpServletRequest;
022
023import org.springframework.beans.factory.annotation.Autowired;
024import org.springframework.beans.factory.annotation.Value;
025import org.springframework.security.core.Authentication;
026import org.springframework.security.core.context.SecurityContextHolder;
027import org.springframework.util.Assert;
028
029import cz.tdp.kshield.client.UserInfo;
030import cz.tdp.kshield.integration.AuthenticationFactory;
031import cz.tdp.kshield.integration.web.DefaultAuthenticationServiceImpl;
032
033/**
034 * Spring Security 3.0.x/3.1.x based implementation of KeyShield SSO Server AuthenticationService
035 */
036public class SpringAuthenticationServiceImpl extends DefaultAuthenticationServiceImpl
037{
038  /**
039   * @param url KeyShield SSO Server url
040   */
041  @Autowired
042  public SpringAuthenticationServiceImpl(@Value("${kshield.url:}") String url) {
043    super(url);
044  }
045  
046  @Override
047  public boolean authenticate(HttpServletRequest request) {
048    final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
049    
050    if (authentication != null && authentication.isAuthenticated()) {
051      return false;
052    }
053    
054    return super.authenticate(request);
055  }
056  
057  /**
058   * @param request current HTTP request
059   * @param userInfo User data returned by KeyShield SSO Server client
060   * @return true if new authentication was created based on existing mapping
061   */
062  @Override
063  protected boolean doAuthentication(HttpServletRequest request, UserInfo userInfo) {
064    Assert.notNull(authenticationFactory, "Please provide authentication factory instance");
065    
066    final Authentication auth = authenticationFactory.createAuthenication(userInfo);
067    
068    if (auth != null && auth.isAuthenticated()) {
069      SecurityContextHolder.getContext().setAuthentication(auth);
070      return true;
071    }
072    
073    // just return false if username is null
074    return false;
075  }
076
077  @Autowired(required = false)
078  private AuthenticationFactory<Authentication> authenticationFactory;
079
080  /**
081   * You can optionally inject custom implementation of AuthenticationFactory class
082   * @param authenticationFactory - Custom AuthenticationFactory instance
083   */
084  public void setAuthenticationFactory(AuthenticationFactory<Authentication> authenticationFactory) {
085    this.authenticationFactory = authenticationFactory;
086  }
087}