Package io.lumify.web

Source Code of io.lumify.web.X509AuthenticationHandler

package io.lumify.web;

import io.lumify.core.exception.LumifyException;
import io.lumify.core.model.user.UserRepository;
import io.lumify.core.user.User;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import io.lumify.miniweb.HandlerChain;
import org.securegraph.Graph;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.List;

public abstract class X509AuthenticationHandler extends AuthenticationHandler {
    public static final String CERTIFICATE_REQUEST_ATTRIBUTE = "javax.servlet.request.X509Certificate";

    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(X509AuthenticationHandler.class);
    private final UserRepository userRepository;
    private final Graph graph;

    protected X509AuthenticationHandler(UserRepository userRepository, final Graph graph) {
        this.userRepository = userRepository;
        this.graph = graph;
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, HandlerChain chain) throws Exception {
        String userId = CurrentUser.get(request);
        if (userId == null) {
            X509Certificate cert = extractCertificate(request);
            if (isInvalid(cert)) {
                respondWithAuthenticationFailure(response);
                return;
            }

            User user = getUser(request, cert);
            if (user == null) {
                respondWithAuthenticationFailure(response);
                return;
            }
            userRepository.recordLogin(user, request.getRemoteAddr());
            CurrentUser.set(request, user.getUserId(), user.getUsername());
        }
        chain.next(request, response);
    }

    protected User getUser(HttpServletRequest request, X509Certificate cert) {
        String username = getUsername(cert);
        if (username == null || username.trim().equals("")) {
            return null;
        }
        String displayName = getDisplayName(cert);
        if (displayName == null || displayName.trim().equals("")) {
            return null;
        }
        String randomPassword = UserRepository.createRandomPassword();
        return userRepository.findOrAddUser(username, displayName, null, randomPassword, new String[0]);
    }

    protected boolean isInvalid(X509Certificate cert) {
        if (cert == null) {
            return true;
        }

        try {
            cert.checkValidity();
            return false;
        } catch (CertificateExpiredException e) {
            LOGGER.warn("Authentication attempt with expired certificate: %s", cert.getSubjectDN());
        } catch (CertificateNotYetValidException e) {
            LOGGER.warn("Authentication attempt with certificate that's not yet valid: %s", cert.getSubjectDN());
        }

        return true;
    }

    protected X509Certificate extractCertificate(HttpServletRequest request) {
        X509Certificate[] certs = (X509Certificate[]) request.getAttribute(CERTIFICATE_REQUEST_ATTRIBUTE);
        if (null != certs && certs.length > 0) {
            return certs[0];
        }
        return null;
    }

    protected String getUsername(X509Certificate cert) {
        String dn = getDn(cert);
        if (dn != null) {
            return dn;
        } else {
            throw new LumifyException("failed to get DN from cert for username");
        }
    }

    protected String getDisplayName(X509Certificate cert) {
        String cn = getCn(cert);
        if (cn != null) {
            return cn;
        } else {
            throw new LumifyException("failed to get CN from cert for displayName");
        }
    }

    private String getDn(X509Certificate cert) {
        String dn = cert.getSubjectX500Principal().getName();
        LOGGER.debug("certificate DN is [%s]", dn);
        return dn;
    }

    private String getCn(X509Certificate cert) {
        String dn = getDn(cert);
        try {
            List<Rdn> rdns = new LdapName(dn).getRdns();
            for (int i = rdns.size() - 1; i >= 0; i--) {
                Rdn rdn = rdns.get(i);
                if (rdn.getType().equalsIgnoreCase("CN")) {
                    String cn = rdn.getValue().toString();
                    LOGGER.debug("certificate CN is [%s]", cn);
                    return cn;
                }
            }
        } catch (InvalidNameException ine) {
            return null;
        }
        return null;
    }

    protected void respondWithAuthenticationFailure(HttpServletResponse response) throws IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }

    protected UserRepository getUserRepository() {
        return userRepository;
    }

    protected Graph getGraph() {
        return graph;
    }
}
TOP

Related Classes of io.lumify.web.X509AuthenticationHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.