Search in sources :

Example 51 with SEPASecurityException

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);
}
Also used : ClientAuthorization(it.unibo.arces.wot.sepa.commons.security.ClientAuthorization) SEPASecurityException(it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException) SignedJWT(com.nimbusds.jwt.SignedJWT) Date(java.util.Date) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) ParseException(java.text.ParseException) JOSEException(com.nimbusds.jose.JOSEException) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException) SimpleDateFormat(java.text.SimpleDateFormat) Credentials(it.unibo.arces.wot.sepa.commons.security.Credentials)

Example 52 with SEPASecurityException

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();
    }
}
Also used : SEPASecurityException(it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException) LdapException(org.apache.directory.api.ldap.model.exception.LdapException)

Example 53 with SEPASecurityException

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();
    }
}
Also used : DefaultEntry(org.apache.directory.api.ldap.model.entry.DefaultEntry) Entry(org.apache.directory.api.ldap.model.entry.Entry) Attribute(org.apache.directory.api.ldap.model.entry.Attribute) CursorException(org.apache.directory.api.ldap.model.cursor.CursorException) SEPASecurityException(it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException) IOException(java.io.IOException) LdapException(org.apache.directory.api.ldap.model.exception.LdapException)

Example 54 with SEPASecurityException

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();
    }
}
Also used : CursorException(org.apache.directory.api.ldap.model.cursor.CursorException) SEPASecurityException(it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException) LdapException(org.apache.directory.api.ldap.model.exception.LdapException)

Example 55 with SEPASecurityException

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();
    }
}
Also used : DefaultModification(org.apache.directory.api.ldap.model.entry.DefaultModification) Modification(org.apache.directory.api.ldap.model.entry.Modification) DefaultModification(org.apache.directory.api.ldap.model.entry.DefaultModification) SEPASecurityException(it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException) LdapException(org.apache.directory.api.ldap.model.exception.LdapException)

Aggregations

SEPASecurityException (it.unibo.arces.wot.sepa.commons.exceptions.SEPASecurityException)69 LdapException (org.apache.directory.api.ldap.model.exception.LdapException)29 IOException (java.io.IOException)20 CursorException (org.apache.directory.api.ldap.model.cursor.CursorException)18 ErrorResponse (it.unibo.arces.wot.sepa.commons.response.ErrorResponse)15 Response (it.unibo.arces.wot.sepa.commons.response.Response)12 SEPAPropertiesException (it.unibo.arces.wot.sepa.commons.exceptions.SEPAPropertiesException)11 SEPAProtocolException (it.unibo.arces.wot.sepa.commons.exceptions.SEPAProtocolException)10 JsonObject (com.google.gson.JsonObject)7 JsonParser (com.google.gson.JsonParser)7 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)7 DefaultModification (org.apache.directory.api.ldap.model.entry.DefaultModification)7 Modification (org.apache.directory.api.ldap.model.entry.Modification)7 SEPABindingsException (it.unibo.arces.wot.sepa.commons.exceptions.SEPABindingsException)5 Credentials (it.unibo.arces.wot.sepa.commons.security.Credentials)5 HttpEntity (org.apache.http.HttpEntity)5 JOSEException (com.nimbusds.jose.JOSEException)4 SignedJWT (com.nimbusds.jwt.SignedJWT)4 JWTResponse (it.unibo.arces.wot.sepa.commons.response.JWTResponse)4 ParseException (java.text.ParseException)4