Search in sources :

Example 1 with StsRequest

use of com.tremolosecurity.idp.providers.oidc.db.StsRequest 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)

Aggregations

Gson (com.google.gson.Gson)1 LDAPException (com.novell.ldap.LDAPException)1 UrlHolder (com.tremolosecurity.config.util.UrlHolder)1 AuthChainType (com.tremolosecurity.config.xml.AuthChainType)1 StsRequest (com.tremolosecurity.idp.providers.oidc.db.StsRequest)1 OidcSessionState (com.tremolosecurity.idp.providers.oidc.model.OidcSessionState)1 ProvisioningException (com.tremolosecurity.provisioning.core.ProvisioningException)1 AuthController (com.tremolosecurity.proxy.auth.AuthController)1 AuthInfo (com.tremolosecurity.proxy.auth.AuthInfo)1 AzSys (com.tremolosecurity.proxy.auth.AzSys)1 IOException (java.io.IOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)1 InvalidKeyException (java.security.InvalidKeyException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 X509Certificate (java.security.cert.X509Certificate)1 HashMap (java.util.HashMap)1 BadPaddingException (javax.crypto.BadPaddingException)1