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

com.auth0.web.Auth0Filter Maven / Gradle / Ivy

package com.auth0.web;

import com.auth0.Auth0Exception;
import com.auth0.Auth0User;
import com.auth0.SessionUtils;
import com.auth0.Tokens;
import com.auth0.jwt.Algorithm;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.JWTVerifyException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.Validate;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;

import static com.auth0.jwt.pem.PemReader.readPublicKey;

/**
 * Handles interception on a secured endpoint and does JWT Verification
 * Ensures only valid JWTs are permitted on secured endpoints
 * Success and Failure navigation options are configurable
 */
public class Auth0Filter implements Filter {

    private String onFailRedirectTo;

    private JWTVerifier jwtVerifier;

    private Auth0Config auth0Config;

    public Auth0Filter(final Auth0Config auth0Config) {
        this.auth0Config = auth0Config;
    }

    /**
     * Called by the web container to indicate to a filter that it is
     * being placed into service. Initialises configuration setup for this filter
     */
    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        onFailRedirectTo = filterConfig.getInitParameter("redirectOnAuthError");
        Validate.notNull(onFailRedirectTo);
        final String issuer = auth0Config.getIssuer();
        Validate.notNull(issuer);
        final String clientId = auth0Config.getClientId();
        Validate.notNull(clientId);
        final String signingAlgorithmStr = auth0Config.getSigningAlgorithm();
        final Algorithm signingAlgorithm = Algorithm.valueOf(signingAlgorithmStr);
        switch (signingAlgorithm) {
            case HS256:
            case HS384:
            case HS512:
                final String clientSecret = auth0Config.getClientSecret();
                Validate.notNull(clientSecret);
                final boolean base64EncodedSecret = auth0Config.isBase64EncodedSecret();
                // Auth0 Client Secrets are not Base64 encoded by default
                if (base64EncodedSecret) {
                    final Base64 base64 = new Base64(true);
                    jwtVerifier = new JWTVerifier(base64.decode(clientSecret), clientId, issuer);
                } else {
                    jwtVerifier = new JWTVerifier(clientSecret, clientId, issuer);
                }
                return;
            case RS256:
            case RS384:
            case RS512:
                final String publicKeyPath = auth0Config.getPublicKeyPath();
                Validate.notEmpty(publicKeyPath);
                try {
                    final ServletContext context = filterConfig.getServletContext();
                    final String publicKeyRealPath = context.getRealPath(publicKeyPath);
                    final PublicKey publicKey = readPublicKey(publicKeyRealPath);
                    Validate.notNull(publicKey);
                    jwtVerifier = new JWTVerifier(publicKey, clientId, issuer);
                    return;
                } catch (Exception e) {
                    throw new IllegalStateException(e.getMessage(), e.getCause());
                }
            default:
                throw new IllegalStateException("Unsupported signing method: " + signingAlgorithm.getValue());
        }

    }

    /**
     * Navigation to take when a request is successful by this filter
     */
    protected void onSuccess(final ServletRequest req, final ServletResponse res, final FilterChain next,
                             final Auth0User auth0User) throws IOException, ServletException {
        final Auth0RequestWrapper auth0RequestWrapper = new Auth0RequestWrapper((HttpServletRequest) req, auth0User);
        next.doFilter(auth0RequestWrapper, res);
    }

    /**
     * Navigation to take when a request is rejected by this filter
     */
    protected void onReject(final HttpServletResponse res) throws IOException, ServletException {
        res.sendRedirect(onFailRedirectTo);
    }

    /**
     * Check for existence of id token and access token
     *
     * @param tokens the tokens object
     * @return boolean whether both id token and access token exist
     */
    protected boolean tokensExist(final Tokens tokens) {
        if (tokens == null) {
            return false;
        }
        return tokens.getIdToken() != null && tokens.getAccessToken() != null;
    }

    /**
     * Perform filter check on this request - verify tokens exist and verify
     * the id token is valid
     */
    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain next) throws IOException, ServletException {
        final HttpServletRequest req = (HttpServletRequest) request;
        final HttpServletResponse res = (HttpServletResponse) response;
        final Tokens tokens = SessionUtils.getTokens(req);
        if (!tokensExist(tokens)) {
            onReject(res);
            return;
        }
        try {
            jwtVerifier.verify(tokens.getIdToken());
            final Auth0User auth0User = SessionUtils.getAuth0User(req);
            onSuccess(req, res, next, auth0User);
        } catch (InvalidKeyException e) {
            throw new Auth0Exception("InvalidKeyException thrown while decoding JWT token " + e.getLocalizedMessage());
        } catch (NoSuchAlgorithmException e) {
            throw new Auth0Exception("NoSuchAlgorithmException thrown while decoding JWT token " + e.getLocalizedMessage());
        } catch (IllegalStateException e) {
            throw new Auth0Exception("IllegalStateException thrown while decoding JWT token " + e.getLocalizedMessage());
        } catch (SignatureException e) {
            throw new Auth0Exception("SignatureException thrown while decoding JWT token " + e.getLocalizedMessage());
        } catch (IOException e) {
            throw new Auth0Exception("IOException thrown while decoding JWT token " + e.getLocalizedMessage());
        } catch (JWTVerifyException e) {
            throw new Auth0Exception("JWTVerifyException thrown while decoding JWT token " + e.getLocalizedMessage());
        }
    }

    @Override
    public void destroy() {
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy