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);
}
}
}
}
Aggregations