All Downloads are FREE. Search and download functionalities are using the official Maven repository.

leap.web.security.authc.DefaultTokenAuthenticationManager Maven / Gradle / Ivy

There is a newer version: 0.7.13b
Show newest version
/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package leap.web.security.authc;

import leap.core.AppConfigException;
import leap.core.BeanFactory;
import leap.core.annotation.Inject;
import leap.core.ioc.PostCreateBean;
import leap.core.security.Authentication;
import leap.core.security.Credentials;
import leap.core.security.UserPrincipal;
import leap.core.security.token.SimpleTokenCredentials;
import leap.core.security.token.TokenCredentials;
import leap.core.security.token.TokenVerifyException;
import leap.lang.Out;
import leap.lang.Result;
import leap.lang.Strings;
import leap.lang.codec.Base64;
import leap.lang.intercepting.State;
import leap.lang.logging.Log;
import leap.lang.logging.LogFactory;
import leap.web.Request;
import leap.web.Response;
import leap.web.security.SecurityConfig;
import leap.web.security.SecuritySessionManager;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import java.io.IOException;

public class DefaultTokenAuthenticationManager extends CookieBasedAuthenticationResolver implements TokenAuthenticationManager,PostCreateBean {
	
	private static final Log log = LogFactory.get(DefaultTokenAuthenticationManager.class);
	
    protected @Inject SecurityConfig         securityConfig;
    protected @Inject SecuritySessionManager sessionManager;

	protected TokenAuthenticator tokenAuthenticator;
	protected String  			 logoutToken;
	
	public String getLogoutToken() {
		if(null == logoutToken) {
			logoutToken = Base64.urlEncode("logout");
		}
		return logoutToken;
	}

	public void setLogoutToken(String token) {
		this.logoutToken = token;
	}

    @Override
    public State preResolveAuthentication(Request request, Response response, AuthenticationContext context) throws Throwable {
        if(!securityConfig.isAuthenticationTokenEnabled()) {
            return State.CONTINUE;
        }

        String token = getToken(request);

        if(getLogoutToken().equals(token)){
            sessionManager.removeAuthentication(request);
        }

        context.setAuthenticationToken(token);

        return State.CONTINUE;
    }

    @Override
	public Result resolveAuthentication(Request request, Response response, AuthenticationContext context) throws ServletException, IOException {
		if(!securityConfig.isAuthenticationTokenEnabled()) {
            return Result.empty();
        }

		String token = context.getAuthenticationToken();
		if(Strings.isEmpty(token)) {
			return Result.empty();
		}

        if(getLogoutToken().equals(token)){
            return Result.empty();
        }

		TokenCredentials   credentials  = new SimpleTokenCredentials(token);
		Out outPrincipal = new Out<>();
		try {
		    if(log.isDebugEnabled()) {
		        log.debug("Authenticates the auth token : {}", Strings.abbreviate(token, 10) + "******");
		    }
		    
	        if(!tokenAuthenticator.authenticate(context, credentials, outPrincipal)) {
	        	return Result.empty();
	        }
        } catch (TokenVerifyException e) {
        	log.info("Token verify error, " + e.getMessage(), e);
        	removeCookie(request, response);
        	return Result.empty();
        }
		
		UserPrincipal principal = outPrincipal.getValue();
		if(null == principal){
			throw new IllegalStateException("Credentials '" + credentials + "' authenticated but no principal was returned");
		}
		
        Authentication authc = sessionManager.getAuthentication(request);
		if(null != authc && !principal.getId().equals(authc.getUser().getId())) {
			sessionManager.removeAuthentication(request);
		}

        authc = new TokenAuthentication(principal, credentials);
        authc.setToken(token);

		return Result.of(authc);
	}

	@Override
	public void onLoginSuccess(Request request, Response response, Authentication authc) {
        if(authc instanceof TokenAuthentication) {
            return;
        }
		if(null == authc.getToken()){
			String token = tokenAuthenticator.generateAuthenticationToken(request, response, authc);
			authc.setToken(token);
		}
		setCookie(request, response, authc.getToken());
	}

	@Override
    public void onLogoutSuccess(Request request, Response response) {
		setCookie(request, response, getLogoutToken());
	}

	protected String getToken(Request request) {
		String token = request.getHeader(securityConfig.getAuthenticationTokenHeaderName());
		if(Strings.isEmpty(token)) {
			Cookie cookie = request.getCookie(getCookieName(request));
			if(null != cookie) {
				token = cookie.getValue();
			}
		}
		
		return token;
	}
	
	@Override
	public int getCookieExpires() {
	    return -1;
    }

	@Override
	public String getCookieName() {
	    return securityConfig.getAuthenticationTokenCookieName();
    }

	@Override
	public String getCookieExpiresParameter() {
	    return null;
    }

	@Override
    public void postCreate(BeanFactory factory) throws Throwable {
	    String tokenType = securityConfig.getAuthenticationTokenType();
	    if(Strings.isEmpty(tokenType)) {
	    	throw new AppConfigException("Default token type must be configured for token based authentication");
	    }
	    
	    this.tokenAuthenticator = factory.tryGetBean(TokenAuthenticator.class, tokenType);
	    if(null == this.tokenAuthenticator) {
	    	throw new AppConfigException("Bean of type '" + TokenAuthenticator.class.getSimpleName() + "' and named '" + tokenType + "' does not exists");
	    }
    }

    protected static final class TokenAuthentication extends SimpleAuthentication {
        public TokenAuthentication(UserPrincipal user, Credentials credentials) {
            super(user, credentials);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy