use of it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException in project SEPA by arces-wot.
the class SecurityManager method validateToken.
/**
* Operation when receiving a request at a protected endpoint
*
* <pre>
* Specific to HTTP request:
* 1. Check if the request contains an Authorization header.
* 2. Check if the request contains an Authorization: Bearer-header with non-null/empty contents
* 3. Check if the value of the Authorization: Bearer-header is a JWT object
*
* Token validation:
* 4. Check if the JWT object is signed
* 5. Check if the signature of the JWT object is valid. This is to be checked with AS public signature verification key
* 6. Check the contents of the JWT object
* 7. Check if the value of "iss" is https://wot.arces.unibo.it:8443/oauth/token
* 8. Check if the value of "aud" contains https://wot.arces.unibo.it:8443/sparql
* 9. Accept the request as well as "sub" as the originator of the request and process it as usual
*
* Respond with 401 if not
*
* According to RFC6749, the error member can assume the following values: invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope.
*
* invalid_request
* The request is missing a required parameter, includes an
* unsupported parameter value (other than grant type),
* repeats a parameter, includes multiple credentials,
* utilizes more than one mechanism for authenticating the
* client, or is otherwise malformed.
*
* invalid_client
* Client authentication failed (e.g., unknown client, no
* client authentication included, or unsupported
* authentication method). The authorization server MAY
* return an HTTP 401 (Unauthorized) status code to indicate
* which HTTP authentication schemes are supported. If the
* client attempted to authenticate via the "Authorization"
* request header field, the authorization server MUST
* respond with an HTTP 401 (Unauthorized) status code and
* include the "WWW-Authenticate" response header field
* matching the authentication scheme used by the client.
*
* invalid_grant
* The provided authorization grant (e.g., authorization
* code, resource owner credentials) or refresh token is
* invalid, expired, revoked, does not match the redirection
* URI used in the authorization request, or was issued to
* another client.
*
* unauthorized_client
* The authenticated client is not authorized to use this
* authorization grant type.
*
* unsupported_grant_type
* The authorization grant type is not supported by the
* authorization server.
*
* </pre>
*
* @param accessToken the JWT token to be validate according to points 4-6
*/
public synchronized ClientAuthorization validateToken(String accessToken) {
logger.debug("VALIDATE TOKEN");
// Parse token
SignedJWT signedJWT = null;
try {
signedJWT = SignedJWT.parse(accessToken);
} catch (ParseException e) {
logger.error(e.getMessage());
return new ClientAuthorization("invalid_request", "ParseException: " + e.getMessage());
}
// Verify token
try {
if (!signedJWT.verify(verifier)) {
logger.error("Signed JWT not verified");
return new ClientAuthorization("invalid_grant", "Signed JWT not verified");
}
} catch (JOSEException e) {
logger.error(e.getMessage());
return new ClientAuthorization("invalid_grant", "JOSEException: " + e.getMessage());
}
// Process token (validate)
JWTClaimsSet claimsSet = null;
try {
claimsSet = jwtProcessor.process(accessToken, new SEPASecurityContext());
} catch (ParseException e) {
logger.error(e.getMessage());
return new ClientAuthorization("invalid_grant", "ParseException. " + e.getMessage());
} catch (BadJOSEException e) {
logger.error(e.getMessage());
return new ClientAuthorization("invalid_grant", "BadJOSEException. " + e.getMessage());
} catch (JOSEException e) {
logger.error(e.getMessage());
return new ClientAuthorization("invalid_grant", "JOSEException. " + e.getMessage());
}
// Check token expiration (an "invalid_grant" error is raised if the token is expired)
Date now = new Date();
long nowUnixSeconds = (now.getTime() / 1000) * 1000;
Date expiring = claimsSet.getExpirationTime();
Date notBefore = claimsSet.getNotBeforeTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
if (expiring.getTime() - nowUnixSeconds < 0) {
logger.warn("Token is expired: " + sdf.format(claimsSet.getExpirationTime()) + " < " + sdf.format(new Date(nowUnixSeconds)));
return new ClientAuthorization("invalid_grant", "Token issued at " + sdf.format(claimsSet.getIssueTime()) + " is expired: " + sdf.format(claimsSet.getExpirationTime()) + " < " + sdf.format(now));
}
if (notBefore != null && nowUnixSeconds < notBefore.getTime()) {
logger.warn("Token can not be used before: " + claimsSet.getNotBeforeTime());
return new ClientAuthorization("invalid_grant", "Token can not be used before: " + claimsSet.getNotBeforeTime());
}
// Get client credentials for accessing the SPARQL endpoint
String id = claimsSet.getSubject();
logger.debug("Get credentials for uid: " + id);
Credentials cred = null;
try {
cred = getEndpointCredentials(id);
logger.trace(cred);
} catch (SEPASecurityException e) {
logger.error("Failed to retrieve credentials (" + id + ")");
return new ClientAuthorization("invalid_grant", "Failed to get credentials (" + id + ")");
}
return new ClientAuthorization(cred);
}
use of it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException in project SEPA by arces-wot.
the class LdapSecurityManager method removeCredentials.
@Override
public void removeCredentials(DigitalIdentity identity) throws SEPASecurityException {
logger.log(Level.getLevel("ldap"), "[LDAP] removeCredentials " + "uid=" + identity.getUid() + ",ou=credentials," + prop.getBase());
bind();
try {
ldap.delete("uid=" + identity.getUid() + ",ou=credentials," + prop.getBase());
} catch (LdapException e) {
logger.error("[LDAP] checkCredentials exception " + e.getMessage());
throw new SEPASecurityException("checkCredentials exception " + e.getMessage());
} finally {
unbind();
}
}
use of it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException in project SEPA by arces-wot.
the class LdapSecurityManager method getTokenExpiringPeriod.
@Override
public long getTokenExpiringPeriod(String id) throws SEPASecurityException {
bind();
try {
if (id == null) {
logger.log(Level.getLevel("ldap"), "[LDAP] getTokenExpiringPeriod " + "uid=default,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)");
cursor = ldap.search("uid=default,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
if (!cursor.next())
throw new SEPASecurityException("uid=default,uid=expiring,ou=jwt," + prop.getBase() + " NOT FOUND");
} else {
if (id.equals("SEPATest")) {
logger.log(Level.getLevel("ldap"), "[LDAP] getTokenExpiringPeriod " + "uid=" + id + ",uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)");
cursor = ldap.search("uid=" + id + ",uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
} else {
logger.log(Level.getLevel("ldap"), "[LDAP] getTokenExpiringPeriod " + "uid=" + id + ",ou=credentials," + prop.getBase(), "(objectclass=*)");
cursor = ldap.search("uid=" + id + ",ou=credentials," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
}
if (!cursor.next())
throw new LdapException("uid=" + id + ",ou=credentials," + prop.getBase() + " NOT FOUND");
Entry entry = cursor.get();
if (!entry.containsAttribute("pwdGraceExpire")) {
cursor.close();
// APPLICATION
if (entry.hasObjectClass("applicationProcess")) {
cursor = ldap.search("uid=application,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
if (!cursor.next())
throw new LdapException("uid=application,uid=expiring,ou=jwt," + prop.getBase() + " NOT FOUND");
} else // DEVICE
if (entry.hasObjectClass("device")) {
cursor = ldap.search("uid=device,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
if (!cursor.next())
throw new LdapException("uid=device,uid=expiring,ou=jwt," + prop.getBase() + " NOT FOUND");
} else // USER
if (entry.hasObjectClass("inetOrgPerson")) {
cursor = ldap.search("uid=user,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
if (!cursor.next())
throw new LdapException("uid=user,uid=expiring,ou=jwt," + prop.getBase() + " NOT FOUND");
} else
throw new LdapException("ClassObject for " + id + " MUST BE one of the following: device, applicationProcess, inetOrgPerson");
}
}
Entry entry = cursor.get();
Attribute attr = entry.get("pwdGraceExpire");
return Long.parseLong(attr.get().getString());
} catch (LdapException | CursorException | IOException e) {
logger.error("[LDAP] getTokenExpiringPeriod exception " + e.getMessage());
throw new SEPASecurityException("getTokenExpiringPeriod exception " + e.getMessage());
} finally {
unbind();
}
}
use of it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException in project SEPA by arces-wot.
the class LdapSecurityManager method getApplicationExpiringPeriod.
@Override
public long getApplicationExpiringPeriod() throws SEPASecurityException {
logger.log(Level.getLevel("ldap"), "[LDAP] getApplicationExpiringPeriod " + "uid=application,uid=expiring,ou=jwt," + prop.getBase());
bind();
try {
cursor = ldap.search("uid=application,uid=expiring,ou=jwt," + prop.getBase(), "(objectclass=*)", SearchScope.OBJECT, "*");
if (!cursor.next())
throw new SEPASecurityException("uid=application,uid=expiring,ou=jwt," + prop.getBase() + " NOT FOUND");
if (cursor.get().get("pwdGraceExpire") == null)
throw new SEPASecurityException("uid=application,uid=expiring,ou=jwt," + prop.getBase() + " pwdGraceExpire NOT FOUND");
return Long.parseLong(cursor.get().get("pwdGraceExpire").getString());
} catch (LdapException | CursorException e) {
logger.error("getApplicationExpiringPeriod exception " + e.getMessage());
throw new SEPASecurityException("getApplicationExpiringPeriod exception " + e.getMessage());
} finally {
unbind();
}
}
use of it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException in project SEPA by arces-wot.
the class LdapSecurityManager method setTokenExpiringPeriod.
@Override
public void setTokenExpiringPeriod(String uid, long period) throws SEPASecurityException {
logger.log(Level.getLevel("ldap"), "[LDAP] setTokenExpiringPeriod " + uid + " period: " + period + " uid=" + uid + ",ou=credentials," + prop.getBase());
bind();
try {
Modification pwdGraceExpire = new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "pwdGraceExpire", String.format("%d", period));
Modification pwdPolicy = new DefaultModification(ModificationOperation.ADD_ATTRIBUTE, "objectClass", "pwdPolicy");
Modification pwdAttribute = new DefaultModification(ModificationOperation.ADD_ATTRIBUTE, "pwdAttribute", "userPassword");
ldap.modify("uid=" + uid + ",ou=credentials," + prop.getBase(), pwdGraceExpire, pwdPolicy, pwdAttribute);
} catch (LdapException e) {
logger.error("[LDAP] setTokenExpiringPeriod exception " + e.getMessage());
throw new SEPASecurityException("setTokenExpiringPeriod exception " + e.getMessage());
} finally {
unbind();
}
}
Aggregations