Search in sources :

Example 11 with AuthChainType

use of com.tremolosecurity.config.xml.AuthChainType in project OpenUnison by TremoloSecurity.

the class OpenIDConnectAuthMech method doGet.

public void doGet(HttpServletRequest request, HttpServletResponse response, AuthStep as) throws IOException, ServletException {
    HttpSession session = ((HttpServletRequest) request).getSession();
    HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
    ConfigManager cfg = (ConfigManager) request.getAttribute(ProxyConstants.TREMOLO_CFG_OBJ);
    MyVDConnection myvd = cfg.getMyVD();
    String idpURL;
    String loadTokenURL;
    if (authParams.get("issuer") != null) {
        StringBuffer b = new StringBuffer();
        String issuer = authParams.get("issuer").getValues().get(0);
        b.append(issuer);
        if (issuer.charAt(issuer.length() - 1) != '/') {
            b.append('/');
        }
        b.append(".well-known/openid-configuration");
        String discoveryUrl = b.toString();
        OidcIdpUrls idp = this.idpUrls.get(discoveryUrl);
        if (idp == null) {
            idp = new OidcIdpUrls();
            this.idpUrls.put(discoveryUrl, idp);
            BasicHttpClientConnectionManager bhcm = new BasicHttpClientConnectionManager(GlobalEntries.getGlobalEntries().getConfigManager().getHttpClientSocketRegistry());
            RequestConfig rc = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
            CloseableHttpClient http = HttpClients.custom().setConnectionManager(bhcm).setDefaultRequestConfig(rc).build();
            try {
                HttpGet get = new HttpGet(b.toString());
                CloseableHttpResponse resp = http.execute(get);
                if (resp.getStatusLine().getStatusCode() == 200) {
                    String json = EntityUtils.toString(resp.getEntity());
                    resp.close();
                    JSONParser parser = new JSONParser();
                    org.json.simple.JSONObject root = (org.json.simple.JSONObject) parser.parse(json);
                    idp.setIdpUrl((String) root.get("authorization_endpoint"));
                    idp.setTokenUrl((String) root.get("token_endpoint"));
                    idp.setUserInfoUrl((String) root.get("userinfo_endpoint"));
                } else {
                    idp.setIdpUrl(authParams.get("idpURL").getValues().get(0));
                    idp.setTokenUrl(loadTokenURL = authParams.get("loadTokenURL").getValues().get(0));
                }
            } catch (ParseException e) {
                throw new ServletException("Could not parse discovery document", e);
            } finally {
                try {
                    http.close();
                } catch (Throwable e) {
                }
                bhcm.close();
            }
        }
        request.setAttribute(OIDC_IDP, idp);
        idpURL = idp.getIdpUrl();
        loadTokenURL = idp.getTokenUrl();
    } else {
        idpURL = authParams.get("idpURL").getValues().get(0);
        loadTokenURL = authParams.get("loadTokenURL").getValues().get(0);
    }
    String bearerTokenName = authParams.get("bearerTokenName").getValues().get(0);
    String clientid = authParams.get("clientid").getValues().get(0);
    String secret = authParams.get("secretid").getValues().get(0);
    String responseType = authParams.get("responseType").getValues().get(0);
    String scope = authParams.get("scope").getValues().get(0);
    boolean linkToDirectory = Boolean.parseBoolean(authParams.get("linkToDirectory").getValues().get(0));
    String noMatchOU = authParams.get("noMatchOU").getValues().get(0);
    String uidAttr = authParams.get("uidAttr").getValues().get(0);
    String lookupFilter = authParams.get("lookupFilter").getValues().get(0);
    String userLookupClassName = authParams.get("userLookupClassName").getValues().get(0);
    String defaultObjectClass = authParams.get("defaultObjectClass").getValues().get(0);
    boolean forceAuth = authParams.get("forceAuthentication") != null ? authParams.get("forceAuthentication").getValues().get(0).equalsIgnoreCase("true") : true;
    UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
    RequestHolder reqHolder = ((AuthController) session.getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
    StringBuffer b = new StringBuffer();
    URL reqURL = new URL(ProxyTools.getInstance().getHttpsUrl(request.getRequestURL().toString(), request));
    b.append(reqURL.getProtocol()).append("://").append(reqURL.getHost());
    if (reqURL.getPort() != -1) {
        b.append(":").append(reqURL.getPort());
    }
    String urlChain = holder.getUrl().getAuthChain();
    AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
    AuthMechType amt = act.getAuthMech().get(as.getId());
    String authMechName = amt.getName();
    b.append(holder.getConfig().getContextPath()).append(cfg.getAuthMechs().get(authMechName).getUri());
    String hd = authParams.get("hd").getValues().get(0);
    if (request.getParameter("state") == null) {
        // initialize openidconnect
        String state = new BigInteger(130, new SecureRandom()).toString(32);
        request.getSession().setAttribute("UNISON_OPENIDCONNECT_STATE", state);
        StringBuffer redirToSend = new StringBuffer();
        redirToSend.append(idpURL).append("?client_id=").append(URLEncoder.encode(clientid, "UTF-8")).append("&response_type=").append(URLEncoder.encode(responseType, "UTF-8")).append("&scope=").append(URLEncoder.encode(scope, "UTF-8")).append("&redirect_uri=").append(URLEncoder.encode(b.toString(), "UTF-8")).append("&state=").append(URLEncoder.encode("security_token=", "UTF-8")).append(URLEncoder.encode(state, "UTF-8"));
        if (forceAuth) {
            redirToSend.append("&max_age=0");
        }
        if (hd != null && !hd.isEmpty()) {
            redirToSend.append("&hd=").append(hd);
        }
        response.sendRedirect(redirToSend.toString());
    } else {
        String stateFromURL = request.getParameter("state");
        stateFromURL = URLDecoder.decode(stateFromURL, "UTF-8");
        stateFromURL = stateFromURL.substring(stateFromURL.indexOf('=') + 1);
        String stateFromSession = (String) request.getSession().getAttribute("UNISON_OPENIDCONNECT_STATE");
        if (!stateFromSession.equalsIgnoreCase(stateFromURL)) {
            throw new ServletException("Invalid State");
        }
        HttpUriRequest post = null;
        try {
            post = RequestBuilder.post().setUri(new java.net.URI(loadTokenURL)).addParameter("code", request.getParameter("code")).addParameter("client_id", clientid).addParameter("client_secret", secret).addParameter("redirect_uri", b.toString()).addParameter("grant_type", "authorization_code").build();
        } catch (URISyntaxException e) {
            throw new ServletException("Could not create post request");
        }
        BasicHttpClientConnectionManager bhcm = new BasicHttpClientConnectionManager(GlobalEntries.getGlobalEntries().getConfigManager().getHttpClientSocketRegistry());
        RequestConfig rc = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
        CloseableHttpClient http = HttpClients.custom().setConnectionManager(bhcm).setDefaultRequestConfig(rc).build();
        CloseableHttpResponse httpResp = http.execute(post);
        if (httpResp.getStatusLine().getStatusCode() != 200) {
            logger.error("Could not retrieve token : " + httpResp.getStatusLine().getStatusCode() + " / " + httpResp.getStatusLine().getReasonPhrase());
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
        }
        BufferedReader in = new BufferedReader(new InputStreamReader(httpResp.getEntity().getContent()));
        StringBuffer token = new StringBuffer();
        String line = null;
        while ((line = in.readLine()) != null) {
            token.append(line);
        }
        httpResp.close();
        bhcm.close();
        Gson gson = new Gson();
        Map tokenNVP = com.cedarsoftware.util.io.JsonReader.jsonToMaps(token.toString());
        String accessToken;
        // Store the bearer token for use by Unison
        request.getSession().setAttribute(bearerTokenName, tokenNVP.get("access_token"));
        Map jwtNVP = null;
        LoadUserData loadUser = null;
        try {
            loadUser = (LoadUserData) Class.forName(userLookupClassName).newInstance();
            jwtNVP = loadUser.loadUserAttributesFromIdP(request, response, cfg, authParams, tokenNVP);
        } catch (Exception e) {
            throw new ServletException("Could not load user data", e);
        }
        if (hd != null && !hd.isEmpty()) {
            String hdFromIdToken = (String) jwtNVP.get("hd");
            if (hdFromIdToken != null && !hdFromIdToken.isEmpty()) {
                if (!hdFromIdToken.equalsIgnoreCase(hd)) {
                    as.setSuccess(false);
                    String redirectToURL = request.getParameter("target");
                    if (redirectToURL != null && !redirectToURL.isEmpty()) {
                        reqHolder.setURL(redirectToURL);
                    }
                }
            } else {
                as.setSuccess(false);
                String redirectToURL = request.getParameter("target");
                if (redirectToURL != null && !redirectToURL.isEmpty()) {
                    reqHolder.setURL(redirectToURL);
                }
            }
        }
        if (jwtNVP == null) {
            as.setSuccess(false);
        } else {
            if (!linkToDirectory) {
                loadUnlinkedUser(session, noMatchOU, uidAttr, act, jwtNVP, defaultObjectClass);
                as.setSuccess(true);
            } else {
                lookupUser(as, session, myvd, noMatchOU, uidAttr, lookupFilter, act, jwtNVP, defaultObjectClass);
            }
            String redirectToURL = request.getParameter("target");
            if (redirectToURL != null && !redirectToURL.isEmpty()) {
                reqHolder.setURL(redirectToURL);
            }
        }
        holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
    }
}
Also used : HttpUriRequest(org.apache.http.client.methods.HttpUriRequest) LDAPAttribute(com.novell.ldap.LDAPAttribute) Attribute(com.tremolosecurity.saml.Attribute) HashMap(java.util.HashMap) HttpGet(org.apache.http.client.methods.HttpGet) Gson(com.google.gson.Gson) URISyntaxException(java.net.URISyntaxException) RequestHolder(com.tremolosecurity.proxy.auth.RequestHolder) URL(java.net.URL) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) UrlHolder(com.tremolosecurity.config.util.UrlHolder) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) AuthChainType(com.tremolosecurity.config.xml.AuthChainType) LoadUserData(com.tremolosecurity.unison.proxy.auth.openidconnect.sdk.LoadUserData) BasicHttpClientConnectionManager(org.apache.http.impl.conn.BasicHttpClientConnectionManager) MyVDConnection(com.tremolosecurity.proxy.myvd.MyVDConnection) RequestConfig(org.apache.http.client.config.RequestConfig) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) InputStreamReader(java.io.InputStreamReader) HttpSession(javax.servlet.http.HttpSession) AuthMechType(com.tremolosecurity.config.xml.AuthMechType) SecureRandom(java.security.SecureRandom) AuthController(com.tremolosecurity.proxy.auth.AuthController) ConfigManager(com.tremolosecurity.config.util.ConfigManager) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) LDAPException(com.novell.ldap.LDAPException) ParseException(org.json.simple.parser.ParseException) IOException(java.io.IOException) JSONObject(org.jose4j.json.internal.json_simple.JSONObject) BufferedReader(java.io.BufferedReader) BigInteger(java.math.BigInteger) JSONParser(org.json.simple.parser.JSONParser) ParseException(org.json.simple.parser.ParseException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 12 with AuthChainType

use of com.tremolosecurity.config.xml.AuthChainType in project OpenUnison by TremoloSecurity.

the class U2fAuth method doGet.

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response, AuthStep as) throws IOException, ServletException {
    if (request.getParameter("signResponse") == null) {
        startAuthentication(request, response, as);
    } else {
        SignResponseHolder srh = gson.fromJson(request.getParameter("signResponse"), SignResponseHolder.class);
        AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        // SharedSession.getSharedSession().getSession(req.getSession().getId());
        HttpSession session = ((HttpServletRequest) request).getSession();
        UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
        RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
        String urlChain = holder.getUrl().getAuthChain();
        AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
        AuthMechType amt = act.getAuthMech().get(as.getId());
        HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
        String challengeStoreAttribute = authParams.get("attribute").getValues().get(0);
        String encyrptionKeyName = authParams.get("encryptionKeyName").getValues().get(0);
        String uidAttributeName = authParams.get("uidAttributeName").getValues().get(0);
        String workflowName = authParams.get("workflowName").getValues().get(0);
        if (srh.getErrorCode() > 0) {
            logger.warn("Browser could not validate u2f token for user '" + userData.getUserDN() + "' : " + srh.getErrorCode());
            if (amt.getRequired().equals("required")) {
                as.setSuccess(false);
            }
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        U2FServer u2f = (U2FServer) request.getSession().getAttribute(SERVER);
        SignResponse sigResp = new SignResponse(srh.getKeyHandle(), srh.getSignatureData(), srh.getClientData(), srh.getSessionId());
        try {
            u2f.processSignResponse(sigResp);
        } catch (U2FException e) {
            logger.warn("Could not authenticate user : '" + e.getMessage() + "'");
            if (amt.getRequired().equals("required")) {
                as.setSuccess(false);
            }
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        String encrypted;
        try {
            encrypted = U2fUtil.encode(u2f.getAllSecurityKeys("doesntmatter"), encyrptionKeyName);
        } catch (Exception e) {
            throw new ServletException("Could not encrypt keys");
        }
        WFCall wc = new WFCall();
        wc.setName(workflowName);
        wc.setUidAttributeName(uidAttributeName);
        TremoloUser tu = new TremoloUser();
        tu.setUid(userData.getAttribs().get(uidAttributeName).getValues().get(0));
        tu.getAttributes().add(new Attribute(uidAttributeName, userData.getAttribs().get(uidAttributeName).getValues().get(0)));
        tu.getAttributes().add(new Attribute(challengeStoreAttribute, encrypted));
        wc.setUser(tu);
        Map<String, Object> req = new HashMap<String, Object>();
        req.put(ProvisioningParams.UNISON_EXEC_TYPE, ProvisioningParams.UNISON_EXEC_SYNC);
        wc.setRequestParams(req);
        try {
            GlobalEntries.getGlobalEntries().getConfigManager().getProvisioningEngine().getWorkFlow(workflowName).executeWorkflow(wc);
        } catch (ProvisioningException e) {
            throw new ServletException("Could not save keys", e);
        }
        as.setSuccess(true);
        holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
    }
}
Also used : AuthInfo(com.tremolosecurity.proxy.auth.AuthInfo) U2FServer(com.google.u2f.server.U2FServer) WFCall(com.tremolosecurity.provisioning.service.util.WFCall) Attribute(com.tremolosecurity.saml.Attribute) HashMap(java.util.HashMap) HttpSession(javax.servlet.http.HttpSession) AuthMechType(com.tremolosecurity.config.xml.AuthMechType) RequestHolder(com.tremolosecurity.proxy.auth.RequestHolder) AuthController(com.tremolosecurity.proxy.auth.AuthController) ServletException(javax.servlet.ServletException) U2FException(com.google.u2f.U2FException) MalformedURLException(java.net.MalformedURLException) ProvisioningException(com.tremolosecurity.provisioning.core.ProvisioningException) IOException(java.io.IOException) HttpServletRequest(javax.servlet.http.HttpServletRequest) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) SignResponse(com.google.u2f.server.messages.SignResponse) TremoloUser(com.tremolosecurity.provisioning.service.util.TremoloUser) ProvisioningException(com.tremolosecurity.provisioning.core.ProvisioningException) U2FException(com.google.u2f.U2FException) AuthChainType(com.tremolosecurity.config.xml.AuthChainType)

Example 13 with AuthChainType

use of com.tremolosecurity.config.xml.AuthChainType in project OpenUnison by TremoloSecurity.

the class TokenData method doPost.

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    if (request.getHeader("Accept") != null && request.getHeader("Accept").startsWith("application/json")) {
        request.setAttribute("com.tremolosecurity.unison.proxy.noRedirectOnError", "com.tremolosecurity.unison.proxy.noRedirectOnError");
    }
    try {
        String action = (String) request.getAttribute(IDP.ACTION_NAME);
        if (action.contentEquals("completefed")) {
            this.completeFederation(request, response);
        } else if (action.equalsIgnoreCase("token")) {
            String code = request.getParameter("code");
            String clientID = request.getParameter("client_id");
            String clientSecret = request.getParameter("client_secret");
            String redirectURI = request.getParameter("redirect_uri");
            String grantType = request.getParameter("grant_type");
            String refreshToken = request.getParameter("refresh_token");
            if (clientID == null) {
                // this means that the clientid is in the Authorization header
                String azHeader = request.getHeader("Authorization");
                azHeader = azHeader.substring(azHeader.indexOf(' ') + 1).trim();
                azHeader = new String(org.apache.commons.codec.binary.Base64.decodeBase64(azHeader));
                clientID = azHeader.substring(0, azHeader.indexOf(':'));
                clientSecret = azHeader.substring(azHeader.indexOf(':') + 1);
            }
            AuthController ac = (AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL);
            UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
            holder.getApp().getCookieConfig().getTimeout();
            if (refreshToken != null) {
                try {
                    refreshToken(response, clientID, clientSecret, refreshToken, holder, request, ac.getAuthInfo());
                } catch (Exception e1) {
                    logger.warn("Could not refresh token", e1);
                    AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
                    response.sendError(401);
                }
            } else if (grantType.equalsIgnoreCase("urn:ietf:params:oauth:grant-type:token-exchange")) {
                StsRequest stsRequest = new StsRequest();
                stsRequest.setAudience(request.getParameter("audience"));
                stsRequest.setDelegation(request.getParameter("actor_token") != null);
                stsRequest.setImpersonation(!stsRequest.isDelegation());
                stsRequest.setSubjectToken(request.getParameter("subject_token"));
                stsRequest.setSubjectTokenType(request.getParameter("subject_token_type"));
                stsRequest.setActorToken(request.getParameter("actor_token"));
                stsRequest.setActorTokenType(request.getParameter("actor_token_type"));
                stsRequest.setImpersonation(stsRequest.getActorToken() == null);
                stsRequest.setDelegation(stsRequest.getActorToken() != null);
                OpenIDConnectTrust trust = this.trusts.get(clientID);
                if (trust == null) {
                    String errorMessage = new StringBuilder().append("Trust '").append(clientID).append("' not found").toString();
                    logger.warn(errorMessage);
                    throw new Exception(errorMessage);
                }
                if (!trust.isSts()) {
                    String errorMessage = new StringBuilder().append("Trust '").append(clientID).append("' not an sts").toString();
                    logger.warn(errorMessage);
                    response.sendError(401);
                    return;
                }
                if (stsRequest.isImpersonation()) {
                    stsImpersontion(request, response, clientID, ac, holder, stsRequest, trust);
                } else {
                    if (!trust.isStsDelegation()) {
                        logger.warn(new StringBuilder().append("clientid '").append(clientID).append("' does not support delegation"));
                        response.sendError(403);
                    }
                    // validate the actor
                    X509Certificate sigCert = GlobalEntries.getGlobalEntries().getConfigManager().getCertificate(this.getJwtSigningKeyName());
                    if (sigCert == null) {
                        logger.error(new StringBuilder().append("JWT Signing Certificate '").append(this.getJwtSigningKeyName()).append("' does not exist").toString());
                        response.sendError(500);
                        return;
                    }
                    StringBuffer issuer = new StringBuffer();
                    // issuer.append(cfg.getAuthIdPPath()).append(this.idpName);
                    issuer.append(holder.getApp().getUrls().getUrl().get(0).getUri());
                    String issuerUrl = ProxyTools.getInstance().getFqdnUrl(issuer.toString(), request);
                    HttpSession session = request.getSession();
                    AuthInfo authData = ((AuthController) session.getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
                    TokenData actorTokenData = this.validateToken(stsRequest.getActorToken(), "actor_token", sigCert.getPublicKey(), issuerUrl, clientID, holder, request, authData, response, false);
                    if (actorTokenData == null) {
                        return;
                    }
                    String uidAttribute = this.getUidAttributeFromMap();
                    if (uidAttribute == null) {
                        logger.error(new StringBuilder().append("IdP ").append(holder.getApp().getName()).append(" does not have a sub attribute mapped to a user attribute").toString());
                        response.sendError(500);
                        return;
                    }
                    String authChainName = null;
                    AuthChainType actorAuthChain = null;
                    if (actorTokenData.amr != null) {
                        authChainName = this.getAmrToAuthChain().get(actorTokenData.amr);
                        if (authChainName != null) {
                            actorAuthChain = GlobalEntries.getGlobalEntries().getConfigManager().getAuthChains().get(authChainName);
                        }
                    }
                    AuthInfo actorAuth = this.jwtToAuthInfo(actorTokenData, uidAttribute, actorAuthChain, authChainName);
                    if (actorAuth == null) {
                        // don't think this can happen
                        logger.error("Could not create user auth object from jwt");
                        response.sendError(500);
                        return;
                    }
                    AzSys azSys = new AzSys();
                    if (!azSys.checkRules(actorAuth, GlobalEntries.getGlobalEntries().getConfigManager(), trust.getClientAzRules(), new HashMap<String, Object>())) {
                        AccessLog.log(AccessEvent.AzFail, holder.getApp(), request, actorAuth, new StringBuilder().append("client not authorized to exchange token for subject '").append(actorTokenData.subjectUid).append("'").toString());
                        response.sendError(403);
                        return;
                    }
                    if (!trust.getAllowedAudiences().contains(stsRequest.getAudience())) {
                        AccessLog.log(AccessEvent.AzFail, holder.getApp(), request, actorAuth, new StringBuilder().append("Audience '").append(stsRequest.getAudience()).append("' is not an authorized audience for sts '").append(trust.getTrustName()).append("'").toString());
                        response.sendError(403);
                        return;
                    }
                    OpenIDConnectTrust targetTrust = this.getTrusts().get(stsRequest.getAudience());
                    if (targetTrust == null) {
                        logger.warn(new StringBuilder().append("Audience '").append(stsRequest.getAudience()).append("' does not exist").toString());
                        response.sendError(404);
                        return;
                    }
                    TokenData subjectTokenData = this.validateToken(stsRequest.getSubjectToken(), "subject_token", sigCert.getPublicKey(), issuerUrl, null, holder, request, authData, response, true);
                    if (subjectTokenData == null) {
                        return;
                    }
                    authChainName = null;
                    actorAuthChain = null;
                    if (subjectTokenData.amr != null) {
                        authChainName = this.getAmrToAuthChain().get(subjectTokenData.amr);
                        if (authChainName != null) {
                            actorAuthChain = GlobalEntries.getGlobalEntries().getConfigManager().getAuthChains().get(authChainName);
                        }
                    }
                    AuthInfo subjectAuth = this.jwtToAuthInfo(subjectTokenData, uidAttribute, actorAuthChain, authChainName);
                    if (subjectAuth == null) {
                        // don't think this can happen
                        logger.error("Could not create user auth object from jwt");
                        response.sendError(500);
                        return;
                    }
                    if (!azSys.checkRules(subjectAuth, GlobalEntries.getGlobalEntries().getConfigManager(), trust.getSubjectAzRules(), new HashMap<String, Object>())) {
                        AccessLog.log(AccessEvent.AzFail, holder.getApp(), request, actorAuth, new StringBuilder().append("client not authorized to exchange token for subject '").append(subjectTokenData.subjectUid).append("'").toString());
                        response.sendError(403);
                        return;
                    }
                    OpenIDConnectAccessToken access = new OpenIDConnectAccessToken();
                    OidcSessionState oidcSession = this.createUserSession(request, stsRequest.getAudience(), holder, targetTrust, subjectAuth.getUserDN(), GlobalEntries.getGlobalEntries().getConfigManager(), access, UUID.randomUUID().toString(), subjectAuth.getAuthChain(), subjectTokenData.root, actorTokenData.root);
                    AccessLog.log(AccessEvent.AzSuccess, holder.getApp(), request, actorAuth, new StringBuilder().append("client '").append(trust.getTrustName()).append("' delegated to by '").append(subjectTokenData.subjectUid).append("', jti : '").append(access.getIdTokenId()).append("'").toString());
                    String idtoken = access.getId_token();
                    access.setRefresh_token(oidcSession.getRefreshToken());
                    Gson gson = new Gson();
                    String json = gson.toJson(access);
                    response.setContentType("application/json");
                    response.getOutputStream().write(json.getBytes("UTF-8"));
                    response.getOutputStream().flush();
                    if (logger.isDebugEnabled()) {
                        logger.debug("Token JSON : '" + json + "'");
                    }
                }
            } else if (grantType.equalsIgnoreCase("client_credentials")) {
                clientCredentialsGrant(request, response, clientID, clientSecret, ac, holder);
            } else {
                completeUserLogin(request, response, code, clientID, clientSecret, holder, ac.getAuthInfo());
            }
        }
    } catch (Throwable t) {
        if (request.getHeader("Accept") != null && request.getHeader("Accept").startsWith("application/json")) {
            response.sendError(500);
            response.setContentType("application/json");
            response.getWriter().print("{\"error\":\"invalid_request\"}");
            logger.error("Sending JSON Error", t);
        } else {
            if (t instanceof ServletException) {
                throw (ServletException) t;
            } else if (t instanceof IOException) {
                throw (IOException) t;
            } else {
                throw new ServletException("Error processing post", t);
            }
        }
    }
}
Also used : AuthInfo(com.tremolosecurity.proxy.auth.AuthInfo) HashMap(java.util.HashMap) HttpSession(javax.servlet.http.HttpSession) Gson(com.google.gson.Gson) IOException(java.io.IOException) AuthController(com.tremolosecurity.proxy.auth.AuthController) ProvisioningException(com.tremolosecurity.provisioning.core.ProvisioningException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) LDAPException(com.novell.ldap.LDAPException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) InvalidJwtException(org.jose4j.jwt.consumer.InvalidJwtException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) JoseException(org.jose4j.lang.JoseException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ParseException(org.json.simple.parser.ParseException) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) MalformedURLException(java.net.MalformedURLException) BadPaddingException(javax.crypto.BadPaddingException) X509Certificate(java.security.cert.X509Certificate) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) AzSys(com.tremolosecurity.proxy.auth.AzSys) StsRequest(com.tremolosecurity.idp.providers.oidc.db.StsRequest) AuthChainType(com.tremolosecurity.config.xml.AuthChainType) OidcSessionState(com.tremolosecurity.idp.providers.oidc.model.OidcSessionState)

Example 14 with AuthChainType

use of com.tremolosecurity.config.xml.AuthChainType in project OpenUnison by TremoloSecurity.

the class TokenData method doGet.

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    if (request.getHeader("Accept") != null && request.getHeader("Accept").startsWith("application/json")) {
        request.setAttribute("com.tremolosecurity.unison.proxy.noRedirectOnError", "com.tremolosecurity.unison.proxy.noRedirectOnError");
    }
    String action = (String) request.getAttribute(IDP.ACTION_NAME);
    UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
    if (holder == null) {
        throw new ServletException("Holder is null");
    }
    AuthController ac = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL));
    if (action.equalsIgnoreCase(".well-known/openid-configuration")) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String json = gson.toJson(new OpenIDConnectConfig(this.authURI, request, mapper));
        response.setContentType("application/json");
        response.getWriter().print(json);
        AccessLog.log(AccessEvent.AzSuccess, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
        return;
    } else if (action.equalsIgnoreCase("certs")) {
        try {
            X509Certificate cert = GlobalEntries.getGlobalEntries().getConfigManager().getCertificate(this.jwtSigningKeyName);
            JsonWebKey jwk = JsonWebKey.Factory.newJwk(cert.getPublicKey());
            String keyID = buildKID(cert);
            jwk.setKeyId(keyID);
            jwk.setUse("sig");
            jwk.setAlgorithm("RS256");
            response.setContentType("application/json");
            response.getWriter().print(new JsonWebKeySet(jwk).toJson());
            AccessLog.log(AccessEvent.AzSuccess, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
            return;
        } catch (JoseException e) {
            throw new ServletException("Could not generate jwt", e);
        }
    } else if (action.equalsIgnoreCase("auth")) {
        String clientID = request.getParameter("client_id");
        String responseCode = request.getParameter("response_type");
        String scope = request.getParameter("scope");
        String redirectURI = request.getParameter("redirect_uri");
        String state = request.getParameter("state");
        String nonce = request.getParameter("nonce");
        OpenIDConnectTransaction transaction = new OpenIDConnectTransaction();
        transaction.setClientID(clientID);
        transaction.setResponseCode(responseCode);
        transaction.setNonce(nonce);
        StringTokenizer toker = new StringTokenizer(scope, " ", false);
        while (toker.hasMoreTokens()) {
            String token = toker.nextToken();
            transaction.getScope().add(token);
        }
        transaction.setRedirectURI(redirectURI);
        transaction.setState(state);
        OpenIDConnectTrust trust = trusts.get(clientID);
        if (trust == null) {
            StringBuffer b = new StringBuffer();
            b.append(redirectURI).append("?error=unauthorized_client");
            logger.warn("Trust '" + clientID + "' not found");
            response.sendRedirect(b.toString());
            return;
        }
        if (trust.isVerifyRedirect()) {
            if (!trust.getRedirectURI().contains(redirectURI)) {
                StringBuffer b = new StringBuffer();
                b.append(redirectURI).append("?error=unauthorized_client");
                logger.warn("Invalid redirect");
                AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
                response.sendRedirect(b.toString());
                return;
            }
            transaction.setRedirectURI(redirectURI);
        } else {
            transaction.setRedirectURI(redirectURI);
        }
        if (this.scopes == null) {
            if (transaction.getScope().size() == 0 || !transaction.getScope().get(0).equals("openid")) {
                StringBuffer b = new StringBuffer();
                b.append(transaction.getRedirectURI()).append("?error=invalid_scope");
                logger.warn("First scope not openid");
                AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
                response.sendRedirect(b.toString());
                return;
            } else {
                // we don't need the openid scope anymore
                transaction.getScope().remove(0);
            }
        } else {
            for (String indvScope : transaction.getScope()) {
                if (!this.scopes.contains(indvScope)) {
                    StringBuffer b = new StringBuffer();
                    b.append(transaction.getRedirectURI()).append("?error=invalid_scope");
                    logger.warn(new StringBuilder().append("Scope '").append(indvScope).append("' not recognized"));
                    AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, ac.getAuthInfo(), "NONE");
                    response.sendRedirect(b.toString());
                    return;
                }
            }
        }
        String authChain = trust.getAuthChain();
        if (authChain == null) {
            StringBuffer b = new StringBuffer();
            b.append("IdP does not have an authenticaiton chain configured");
            throw new ServletException(b.toString());
        }
        HttpSession session = request.getSession();
        AuthInfo authData = ((AuthController) session.getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        AuthChainType act = holder.getConfig().getAuthChains().get(authChain);
        session.setAttribute(OpenIDConnectIdP.TRANSACTION_DATA, transaction);
        if (authData == null || !authData.isAuthComplete() && !(authData.getAuthLevel() < act.getLevel())) {
            nextAuth(request, response, session, false, act);
        } else {
            if (authData.getAuthLevel() < act.getLevel()) {
                // step up authentication, clear existing auth data
                session.removeAttribute(ProxyConstants.AUTH_CTL);
                holder.getConfig().createAnonUser(session);
                nextAuth(request, response, session, false, act);
            } else {
                StringBuffer b = genFinalURL(request);
                response.sendRedirect(b.toString());
            // TODO if session already exists extend the life of the id_token
            }
        }
    } else if (action.contentEquals("completefed")) {
        this.completeFederation(request, response);
    } else if (action.equalsIgnoreCase("userinfo")) {
        try {
            processUserInfoRequest(request, response);
        } catch (Exception e) {
            throw new ServletException("Could not process userinfo request", e);
        }
    }
}
Also used : AuthInfo(com.tremolosecurity.proxy.auth.AuthInfo) OpenIDConnectConfig(com.tremolosecurity.idp.providers.oidc.model.OpenIDConnectConfig) GsonBuilder(com.google.gson.GsonBuilder) JoseException(org.jose4j.lang.JoseException) HttpSession(javax.servlet.http.HttpSession) JsonWebKey(org.jose4j.jwk.JsonWebKey) Gson(com.google.gson.Gson) JsonWebKeySet(org.jose4j.jwk.JsonWebKeySet) AuthController(com.tremolosecurity.proxy.auth.AuthController) X509Certificate(java.security.cert.X509Certificate) ProvisioningException(com.tremolosecurity.provisioning.core.ProvisioningException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) LDAPException(com.novell.ldap.LDAPException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) InvalidJwtException(org.jose4j.jwt.consumer.InvalidJwtException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) JoseException(org.jose4j.lang.JoseException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ParseException(org.json.simple.parser.ParseException) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) MalformedURLException(java.net.MalformedURLException) BadPaddingException(javax.crypto.BadPaddingException) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) HttpServletRequest(javax.servlet.http.HttpServletRequest) StringTokenizer(java.util.StringTokenizer) AuthChainType(com.tremolosecurity.config.xml.AuthChainType)

Example 15 with AuthChainType

use of com.tremolosecurity.config.xml.AuthChainType in project OpenUnison by TremoloSecurity.

the class WebAuthn method doGet.

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response, AuthStep as) throws IOException, ServletException {
    if (request.getParameter("requestOptions") != null && request.getParameter("requestOptions").equalsIgnoreCase("true")) {
        AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        // SharedSession.getSharedSession().getSession(req.getSession().getId());
        HttpSession session = ((HttpServletRequest) request).getSession();
        UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
        RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
        String urlChain = holder.getUrl().getAuthChain();
        AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
        AuthMechType amt = act.getAuthMech().get(as.getId());
        HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
        String attributeName = authParams.get("attribute").getValues().get(0);
        String encryptionKeyName = authParams.get("encryptionKeyName").getValues().get(0);
        if (userData.getAttribs().get(attributeName) == null) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' does not have attribute '").append(attributeName).append("'");
            logger.warn(sb.toString());
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        WebAuthnUserData webauthnUser = WebAuthnUtils.lookupWebAuthnUserData(userData, attributeName, encryptionKeyName);
        if (webauthnUser == null) {
            throw new ServletException("No webauthn user data, can not happen");
        }
        try {
            Challenge challenge = new DefaultChallenge();
            JSONObject resp = new JSONObject();
            JSONObject publicKey = new JSONObject();
            resp.put("publicKey", publicKey);
            JSONArray allowedCredentials = new JSONArray();
            publicKey.put("allowedCredentials", allowedCredentials);
            for (Authenticator auth : webauthnUser.getAuthenticators()) {
                byte[] credentialId = auth.getAttestedCredentialData().getCredentialId();
                JSONObject credential = new JSONObject();
                allowedCredentials.add(credential);
                credential.put("type", "public-key");
                credential.put("id", Base64UrlUtil.encodeToString(credentialId));
            }
            publicKey.put("challenge", Base64UrlUtil.encodeToString(challenge.getValue()));
            publicKey.put("rpId", WebAuthnRegistration.getRpId(request));
            publicKey.put("timeout", 30000);
            publicKey.put("userVerification", authParams.get("userVerificationRequirement").getValues().get(0));
            ServerProperty serverProperty = new ServerProperty(new Origin(request.getRequestURL().toString()), WebAuthnRegistration.getRpId(request), challenge, webauthnUser.getId());
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = null;
            byte[] yourBytes = null;
            try {
                out = new ObjectOutputStream(bos);
                out.writeObject(serverProperty);
                out.flush();
                yourBytes = bos.toByteArray();
            } finally {
                try {
                    bos.close();
                } catch (IOException ex) {
                // ignore close exception
                }
            }
            resp.put("serverProperty", java.util.Base64.getUrlEncoder().encodeToString(yourBytes));
            response.getWriter().println(resp.toString());
        } catch (Exception e) {
            throw new ServletException(e);
        }
    } else {
        AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        // SharedSession.getSharedSession().getSession(req.getSession().getId());
        HttpSession session = ((HttpServletRequest) request).getSession();
        UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
        RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
        String urlChain = holder.getUrl().getAuthChain();
        AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
        AuthMechType amt = act.getAuthMech().get(as.getId());
        HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
        String formURI = authParams.get("formURI").getValues().get(0);
        request.getRequestDispatcher(formURI).forward(request, response);
    }
}
Also used : Origin(com.webauthn4j.data.client.Origin) Attribute(com.tremolosecurity.saml.Attribute) HashMap(java.util.HashMap) ObjectOutputStream(java.io.ObjectOutputStream) Challenge(com.webauthn4j.data.client.challenge.Challenge) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) HttpServletRequest(javax.servlet.http.HttpServletRequest) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) AuthChainType(com.tremolosecurity.config.xml.AuthChainType) Authenticator(com.webauthn4j.authenticator.Authenticator) ServerProperty(com.webauthn4j.server.ServerProperty) HttpSession(javax.servlet.http.HttpSession) WebAuthnUserData(com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData) JSONArray(org.json.simple.JSONArray) AuthMechType(com.tremolosecurity.config.xml.AuthMechType) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ValidationException(com.webauthn4j.validator.exception.ValidationException) ServletException(javax.servlet.ServletException) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ParseException(org.json.simple.parser.ParseException) IOException(java.io.IOException) JSONObject(org.json.simple.JSONObject)

Aggregations

AuthChainType (com.tremolosecurity.config.xml.AuthChainType)52 UrlHolder (com.tremolosecurity.config.util.UrlHolder)34 AuthMechType (com.tremolosecurity.config.xml.AuthMechType)34 HttpSession (javax.servlet.http.HttpSession)33 HashMap (java.util.HashMap)32 ServletException (javax.servlet.ServletException)32 Attribute (com.tremolosecurity.saml.Attribute)28 HttpServletRequest (javax.servlet.http.HttpServletRequest)28 IOException (java.io.IOException)21 AuthController (com.tremolosecurity.proxy.auth.AuthController)19 LDAPException (com.novell.ldap.LDAPException)18 LDAPAttribute (com.novell.ldap.LDAPAttribute)17 AuthInfo (com.tremolosecurity.proxy.auth.AuthInfo)14 RequestHolder (com.tremolosecurity.proxy.auth.RequestHolder)13 ProvisioningException (com.tremolosecurity.provisioning.core.ProvisioningException)12 MalformedURLException (java.net.MalformedURLException)10 LDAPSearchResults (com.novell.ldap.LDAPSearchResults)9 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)9 ArrayList (java.util.ArrayList)9 LDAPEntry (com.novell.ldap.LDAPEntry)8