use of com.tremolosecurity.proxy.auth.AuthInfo in project OpenUnison by TremoloSecurity.
the class TokenData method refreshToken.
private void refreshToken(HttpServletResponse response, String clientID, String clientSecret, String refreshToken, UrlHolder holder, HttpServletRequest request, AuthInfo authData) throws Exception, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException, JoseException, InvalidJwtException, UnsupportedEncodingException {
Gson gson = new Gson();
String json = this.inflate(refreshToken);
Token token = gson.fromJson(json, Token.class);
byte[] iv = org.bouncycastle.util.encoders.Base64.decode(token.getIv());
IvParameterSpec spec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, GlobalEntries.getGlobalEntries().getConfigManager().getSecretKey(this.trusts.get(clientID).getCodeLastmileKeyName()), spec);
byte[] encBytes = org.bouncycastle.util.encoders.Base64.decode(token.getEncryptedRequest());
String decryptedRefreshToken = new String(cipher.doFinal(encBytes));
OidcSessionState session = this.getSessionByRefreshToken(decryptedRefreshToken);
if (session == null) {
logger.warn("Session does not exist from refresh_token");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
return;
}
if (!session.getRefreshToken().equals(refreshToken)) {
logger.warn("Session does not exist from refresh_token");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
return;
}
OpenIDConnectTrust trust = this.trusts.get(session.getClientID());
if (!trust.isPublicEndpoint()) {
if (!trust.getClientSecret().equals(clientSecret)) {
logger.warn("Invalid client_secret");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
return;
}
}
if (session.getExpires().isBeforeNow()) {
logger.warn("Session expired");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
this.sessionStore.deleteSession(session.getSessionID());
return;
}
JsonWebSignature jws = new JsonWebSignature();
jws.setCompactSerialization(this.decryptToken(this.trusts.get(session.getClientID()).getCodeLastmileKeyName(), gson, session.getEncryptedIdToken()));
jws.setKey(GlobalEntries.getGlobalEntries().getConfigManager().getCertificate(this.jwtSigningKeyName).getPublicKey());
if (!jws.verifySignature()) {
logger.warn("id_token tampered with");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
return;
}
JwtClaims claims = JwtClaims.parse(jws.getPayload());
// a unique identifier for the token
claims.setGeneratedJwtId();
// when the token was issued/created (now)
claims.setIssuedAtToNow();
// time before which the token is not yet valid (2 minutes ago)
claims.setNotBeforeMinutesInThePast(trusts.get(clientID).getAccessTokenSkewMillis() / 1000 / 60);
// time when the token will expire (10 minutes from now)
claims.setExpirationTimeMinutesInTheFuture(trusts.get(clientID).getAccessTokenTimeToLive() / 1000 / 60);
jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(GlobalEntries.getGlobalEntries().getConfigManager().getPrivateKey(this.jwtSigningKeyName));
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
String newIdToken = jws.getCompactSerialization();
session.setEncryptedIdToken(this.encryptToken(this.trusts.get(session.getClientID()).getCodeLastmileKeyName(), gson, newIdToken));
jws = new JsonWebSignature();
jws.setKey(GlobalEntries.getGlobalEntries().getConfigManager().getCertificate(this.jwtSigningKeyName).getPublicKey());
jws.setCompactSerialization(this.decryptToken(this.trusts.get(session.getClientID()).getCodeLastmileKeyName(), gson, session.getEncryptedAccessToken()));
if (!jws.verifySignature()) {
logger.warn("access_token tampered with");
AccessLog.log(AccessEvent.AzFail, holder.getApp(), (HttpServletRequest) request, authData, "NONE");
response.sendError(401);
return;
}
claims = JwtClaims.parse(jws.getPayload());
// a unique identifier for the token
claims.setGeneratedJwtId();
// when the token was issued/created (now)
claims.setIssuedAtToNow();
// time before which the token is not yet valid (2 minutes ago)
claims.setNotBeforeMinutesInThePast(trusts.get(clientID).getAccessTokenSkewMillis() / 1000 / 60);
// time when the token will expire (10 minutes from now)
claims.setExpirationTimeMinutesInTheFuture(trusts.get(clientID).getAccessTokenTimeToLive() / 1000 / 60);
jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(GlobalEntries.getGlobalEntries().getConfigManager().getPrivateKey(this.jwtSigningKeyName));
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
jws.setKeyIdHeaderValue(this.buildKID(GlobalEntries.getGlobalEntries().getConfigManager().getCertificate(this.jwtSigningKeyName)));
String newAccessToken = jws.getCompactSerialization();
session.setEncryptedAccessToken(this.encryptToken(trust.getCodeLastmileKeyName(), gson, newAccessToken));
String b64 = encryptToken(trusts.get(clientID).getCodeLastmileKeyName(), gson, session.getSessionID());
session.setRefreshToken(b64);
session.setExpires(new DateTime().plusSeconds(holder.getApp().getCookieConfig().getTimeout()));
this.sessionStore.resetSession(session);
OpenIDConnectAccessToken access = new OpenIDConnectAccessToken();
access.setAccess_token(newAccessToken);
access.setExpires_in((int) (trusts.get(clientID).getAccessTokenTimeToLive() / 1000));
access.setId_token(newIdToken);
access.setToken_type("Bearer");
access.setRefresh_token(session.getRefreshToken());
json = gson.toJson(access);
response.setContentType("text/json");
response.getOutputStream().write(json.getBytes());
response.getOutputStream().flush();
AuthInfo remUser = new AuthInfo();
remUser.setUserDN(session.getUserDN());
AccessLog.log(AccessEvent.AzSuccess, holder.getApp(), (HttpServletRequest) request, remUser, "NONE");
}
use of com.tremolosecurity.proxy.auth.AuthInfo in project OpenUnison by TremoloSecurity.
the class TokenData method jwtToAuthInfo.
private AuthInfo jwtToAuthInfo(TokenData td, String uidAttr, AuthChainType act, String subjectAuthMethod) throws ServletException {
String filter = "";
if (td.subjectUid == null) {
filter = "(!(objectClass=*))";
} else {
filter = equal(uidAttr, td.subjectUid).toString();
}
try {
String root = act.getRoot();
if (root == null || root.trim().isEmpty()) {
root = GlobalEntries.getGlobalEntries().getConfigManager().getCfg().getLdapRoot();
}
AuthChainType actForSubject = GlobalEntries.getGlobalEntries().getConfigManager().getAuthChains().get(subjectAuthMethod);
if (actForSubject == null) {
logger.warn(new StringBuilder("No authentication chain named '").append(subjectAuthMethod).append("'"));
}
LDAPSearchResults res = GlobalEntries.getGlobalEntries().getConfigManager().getMyVD().search(root, 2, filter, new ArrayList<String>());
if (res.hasMore()) {
LDAPEntry entry = res.next();
AuthInfo authInfo = new AuthInfo(entry.getDN(), null, actForSubject != null ? actForSubject.getName() : null, actForSubject != null ? actForSubject.getLevel() : 0);
User user = new User(entry);
user = this.getMapper().mapUser(user);
for (String attrName : user.getAttribs().keySet()) {
authInfo.getAttribs().put(attrName, user.getAttribs().get(attrName));
}
if (authInfo.getAttribs().get(uidAttr) == null) {
authInfo.getAttribs().put(uidAttr, new Attribute(uidAttr, td.subjectUid));
}
return authInfo;
} else {
String dn = new StringBuilder().append(uidAttr).append("=").append(td.subjectUid).append(",ou=oauth2,").append(GlobalEntries.getGlobalEntries().getConfigManager().getCfg().getLdapRoot()).toString();
AuthInfo authInfo = new AuthInfo(dn, null, actForSubject != null ? actForSubject.getName() : null, actForSubject != null ? actForSubject.getLevel() : 0);
for (Object key : td.root.keySet()) {
Attribute attr = new Attribute(key.toString());
if (attr.getName().equalsIgnoreCase("sub")) {
authInfo.getAttribs().put(uidAttr, new Attribute(uidAttr, (String) td.root.get(key)));
}
if (td.root.get(key) instanceof JSONArray) {
attr.getValues().addAll(((JSONArray) td.root.get(key)));
} else {
attr.getValues().add(td.root.get(key).toString());
}
authInfo.getAttribs().put((String) key, attr);
return authInfo;
}
}
} catch (LDAPException | ProvisioningException e) {
throw new ServletException("Could not lookup sts subject", e);
}
return null;
}
use of com.tremolosecurity.proxy.auth.AuthInfo in project OpenUnison by TremoloSecurity.
the class TokenData method clientCredentialsGrant.
private void clientCredentialsGrant(HttpServletRequest request, HttpServletResponse response, String clientID, String clientSecret, AuthController ac, UrlHolder holder) throws Exception, IOException, ServletException {
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.isEnableClientCredentialGrant()) {
logger.error(new StringBuilder().append("Trust '").append(clientID).append("' does not support the client_credentials grant").toString());
response.sendError(403);
return;
}
String authChain = trust.getAuthChain();
if (authChain == null) {
if (trust.isPublicEndpoint()) {
StringBuffer b = new StringBuffer();
b.append("IdP does not have an authenticaiton chain configured, but is set to public");
throw new ServletException(b.toString());
} else {
if (clientSecret == null || !clientSecret.equals(trust.getClientSecret())) {
logger.warn(new StringBuilder().append("Invalid client secret for '").append(clientID).append("'"));
response.sendError(401);
} else {
HttpSession session = request.getSession();
AuthInfo authData = new AuthInfo();
authData.setUserDN(new StringBuilder().append("uid=").append(clientID).append(",ou=oauth2,").append(GlobalEntries.getGlobalEntries().getConfigManager().getCfg().getLdapRoot()).toString());
authData.setAuthLevel(0);
authData.setAuthChain("anonymous");
authData.getAttribs().put("uid", new Attribute("uid", clientID));
authData.getAttribs().put("sub", new Attribute("sub", clientID));
authData.getAttribs().put("client", new Attribute("client", "true"));
authData.getAttribs().put("auth_chain", new Attribute("auth_chain", "anonymous"));
authData.getAttribs().put("objectClass", new Attribute("objectClass", GlobalEntries.getGlobalEntries().getConfigManager().getCfg().getUserObjectClass()));
((AuthController) session.getAttribute(ProxyConstants.AUTH_CTL)).setAuthInfo(authData);
AuthChainType act = holder.getConfig().getAuthChains().get(authChain);
OpenIDConnectTransaction transaction = new OpenIDConnectTransaction();
transaction.setClientID(clientID);
session.setAttribute(OpenIDConnectIdP.TRANSACTION_DATA, transaction);
ClientCredentialsGrantPostAuth postAuth = new ClientCredentialsGrantPostAuth(transaction, trust, this);
request.setAttribute(PostAuthSuccess.POST_AUTH_ACTION, postAuth);
postAuth.runAfterSuccessfulAuthentication(request, response, holder, act, null, ac, null);
}
return;
}
}
HttpSession session = request.getSession();
AuthInfo authData = ((AuthController) session.getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
AuthChainType act = holder.getConfig().getAuthChains().get(authChain);
OpenIDConnectTransaction transaction = new OpenIDConnectTransaction();
transaction.setClientID(clientID);
session.setAttribute(OpenIDConnectIdP.TRANSACTION_DATA, transaction);
ClientCredentialsGrantPostAuth postAuth = new ClientCredentialsGrantPostAuth(transaction, trust, this);
request.setAttribute(PostAuthSuccess.POST_AUTH_ACTION, postAuth);
if (authData == null || !authData.isAuthComplete() && !(authData.getAuthLevel() < act.getLevel())) {
nextTokenAuth(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);
nextTokenAuth(request, response, session, false, act);
} else {
// authenticated, next step
postAuth.runAfterSuccessfulAuthentication(request, response, holder, act, null, ac, null);
}
}
}
use of com.tremolosecurity.proxy.auth.AuthInfo in project OpenUnison by TremoloSecurity.
the class TokenData method stsImpersontion.
private void stsImpersontion(HttpServletRequest request, HttpServletResponse response, String clientID, AuthController ac, UrlHolder holder, StsRequest stsRequest, OpenIDConnectTrust trust) throws ServletException, IOException {
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);
OpenIDConnectTransaction transaction = new OpenIDConnectTransaction();
transaction.setClientID(clientID);
session.setAttribute(OpenIDConnectIdP.TRANSACTION_DATA, transaction);
TokenPostAuth postAuth = new TokenPostAuth(transaction, trust, stsRequest, this);
request.setAttribute(PostAuthSuccess.POST_AUTH_ACTION, postAuth);
if (authData == null || !authData.isAuthComplete() && !(authData.getAuthLevel() < act.getLevel())) {
nextTokenAuth(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);
nextTokenAuth(request, response, session, false, act);
} else {
// authenticated, next step
postAuth.runAfterSuccessfulAuthentication(request, response, holder, act, null, ac, null);
}
}
}
use of com.tremolosecurity.proxy.auth.AuthInfo in project OpenUnison by TremoloSecurity.
the class TokenPostAuth method lookupUser.
private AuthInfo lookupUser(HttpSession session, MyVDConnection myvd, String uidAttr, AuthChainType act, String uid, String subjectAuthMethod) throws ServletException {
String filter = "";
StringBuffer b = new StringBuffer();
String userParam = uid;
b.append('(').append(uidAttr).append('=').append(userParam).append(')');
if (userParam == null) {
filter = "(!(objectClass=*))";
} else {
filter = equal(uidAttr, userParam).toString();
}
try {
String root = act.getRoot();
if (root == null || root.trim().isEmpty()) {
root = GlobalEntries.getGlobalEntries().getConfigManager().getCfg().getLdapRoot();
}
LDAPSearchResults res = myvd.search(root, 2, filter, new ArrayList<String>());
if (res.hasMore()) {
LDAPEntry entry = res.next();
AuthChainType actForSubject = GlobalEntries.getGlobalEntries().getConfigManager().getAuthChains().get(subjectAuthMethod);
if (actForSubject == null) {
logger.warn(new StringBuilder("No authentication chain named '").append(subjectAuthMethod).append("'"));
}
AuthInfo authInfo = new AuthInfo(entry.getDN(), (String) session.getAttribute(ProxyConstants.AUTH_MECH_NAME), actForSubject.getName(), actForSubject.getLevel());
User user = new User(entry);
user = idp.getMapper().mapUser(user);
for (String attrName : user.getAttribs().keySet()) {
authInfo.getAttribs().put(attrName, user.getAttribs().get(attrName));
}
return authInfo;
} else {
return null;
}
} catch (LDAPException | ProvisioningException e) {
throw new ServletException("Could not lookup sts subject", e);
}
}
Aggregations