io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProviderBase Maven / Gradle / Ivy
/*
* PowerAuth integration libraries for RESTful API applications, examples and
* related software components
*
* Copyright (C) 2018 Wultra s.r.o.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package io.getlime.security.powerauth.rest.api.spring.provider;
import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes;
import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication;
import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption;
import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException;
import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthRequestFilterException;
import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody;
import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract class for PowerAuth authentication provider.
*
* @author Petr Dvorak, [email protected]
*
*/
public abstract class PowerAuthAuthenticationProviderBase {
private static final Logger logger = LoggerFactory.getLogger(PowerAuthAuthenticationProviderBase.class);
/**
* Validate the signature from the PowerAuth HTTP header against the provided HTTP method, request body and URI identifier.
* Make sure to accept only allowed signatures. Return an instance of PowerAuthApiAuthentication on successful authorization,
* null value is returned on failed authorization. A check of null return value is used to determine the authorization result.
* @param httpMethod HTTP method (GET, POST, ...)
* @param httpBody Body of the HTTP request.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @param allowedSignatureTypes Allowed types of the signature.
* @param forcedSignatureVersion Forced signature version during upgrade.
* @return Instance of a PowerAuthApiAuthentication on successful authorization, null value on failed authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public abstract @Nullable PowerAuthApiAuthentication validateRequestSignature(@Nonnull String httpMethod, @Nullable byte[] httpBody, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes, @Nullable Integer forcedSignatureVersion) throws PowerAuthAuthenticationException;
/**
* Validate the signature from the PowerAuth HTTP header against the provided HTTP method, request body and URI identifier.
* Make sure to accept only allowed signatures. Return an instance of PowerAuthApiAuthentication on both successful and
* failed authorization. A check of null return value cannot be used to determine the authorization result, the actual
* result is available in the authorization context.
* @param httpMethod HTTP method (GET, POST, ...)
* @param httpBody Body of the HTTP request.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @param allowedSignatureTypes Allowed types of the signature.
* @param forcedSignatureVersion Forced signature version during upgrade.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public abstract @Nonnull PowerAuthApiAuthentication validateRequestSignatureWithActivationDetails(@Nonnull String httpMethod, @Nullable byte[] httpBody, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes, @Nullable Integer forcedSignatureVersion) throws PowerAuthAuthenticationException;
/**
* Validate the token digest from PowerAuth authentication header.
* @param httpAuthorizationHeader HTTP header with token digest.
* @param allowedSignatureTypes Allowed types of the signature.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public abstract @Nullable PowerAuthApiAuthentication validateToken(@Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes) throws PowerAuthAuthenticationException;
/**
* Validate the token digest from PowerAuth authentication header.
* @param httpAuthorizationHeader HTTP header with token digest.
* @param allowedSignatureTypes Allowed types of the signature.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public abstract @Nonnull PowerAuthApiAuthentication validateTokenWithActivationDetails(@Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes) throws PowerAuthAuthenticationException;
/**
* The same as {{@link #validateRequestSignature(String, byte[], String, String, List, Integer)} but uses default accepted signature type (2FA or 3FA) and does not specify forced signature version.
* @param httpMethod HTTP method (GET, POST, ...)
* @param httpBody Request body
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nullable PowerAuthApiAuthentication validateRequestSignature(@Nonnull String httpMethod, @Nullable byte[] httpBody, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader) throws PowerAuthAuthenticationException {
List defaultAllowedSignatureTypes = new ArrayList<>();
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_BIOMETRY);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY);
return this.validateRequestSignature(httpMethod, httpBody, requestUriIdentifier, httpAuthorizationHeader, defaultAllowedSignatureTypes, null);
}
/**
* Validate a request signature, make sure only supported signature types are used, do not use forced signature version during upgrade.
* @param servletRequest HTTPServletRequest with signed data.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @param allowedSignatureTypes Allowed types of signatures.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nullable PowerAuthApiAuthentication validateRequestSignature(@Nonnull HttpServletRequest servletRequest, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes) throws PowerAuthAuthenticationException {
// Get HTTP method and body bytes
String requestMethod = servletRequest.getMethod().toUpperCase();
byte[] requestBodyBytes = extractRequestBodyBytes(servletRequest);
return this.validateRequestSignature(requestMethod, requestBodyBytes, requestUriIdentifier, httpAuthorizationHeader, allowedSignatureTypes, null);
}
/**
* Validate a request signature, make sure only supported signature types are used, do not use forced signature version during upgrade.
* @param servletRequest HTTPServletRequest with signed data.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @param allowedSignatureTypes Allowed types of signatures.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nonnull PowerAuthApiAuthentication validateRequestSignatureWithActivationDetails(@Nonnull HttpServletRequest servletRequest, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes) throws PowerAuthAuthenticationException {
// Get HTTP method and body bytes
String requestMethod = servletRequest.getMethod().toUpperCase();
byte[] requestBodyBytes = extractRequestBodyBytes(servletRequest);
return this.validateRequestSignatureWithActivationDetails(requestMethod, requestBodyBytes, requestUriIdentifier, httpAuthorizationHeader, allowedSignatureTypes, null);
}
/**
* Validate a request signature, make sure only supported signature types are used and allow specification of forced signature version.
* @param servletRequest HTTPServletRequest with signed data.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @param allowedSignatureTypes Allowed types of signatures.
* @param forcedSignatureVersion Forced signature version during upgrade.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nullable PowerAuthApiAuthentication validateRequestSignature(@Nonnull HttpServletRequest servletRequest, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader, @Nonnull List allowedSignatureTypes, @Nullable Integer forcedSignatureVersion) throws PowerAuthAuthenticationException {
// Get HTTP method and body bytes
String requestMethod = servletRequest.getMethod().toUpperCase();
byte[] requestBodyBytes = extractRequestBodyBytes(servletRequest);
return this.validateRequestSignature(requestMethod, requestBodyBytes, requestUriIdentifier, httpAuthorizationHeader, allowedSignatureTypes, forcedSignatureVersion);
}
/**
* The same as {{@link #validateRequestSignature(HttpServletRequest, String, String, List, Integer)} but uses default accepted signature type (2FA or 3FA) and does not specify forced signature version.
* @param servletRequest HTTPServletRequest with signed data.
* @param requestUriIdentifier Request URI identifier.
* @param httpAuthorizationHeader PowerAuth HTTP authorization header.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nullable PowerAuthApiAuthentication validateRequestSignature(@Nonnull HttpServletRequest servletRequest, @Nonnull String requestUriIdentifier, @Nonnull String httpAuthorizationHeader) throws PowerAuthAuthenticationException {
List defaultAllowedSignatureTypes = new ArrayList<>();
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_BIOMETRY);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY);
return this.validateRequestSignature(servletRequest, requestUriIdentifier, httpAuthorizationHeader, defaultAllowedSignatureTypes, null);
}
/**
* Validate the token digest from PowerAuth authentication header.
* @param tokenHeader HTTP header with token digest.
* @return Instance of a PowerAuthApiAuthentication on successful authorization.
* @throws PowerAuthAuthenticationException In case authorization fails, exception is raised.
*/
public @Nullable PowerAuthApiAuthentication validateToken(@Nonnull String tokenHeader) throws PowerAuthAuthenticationException {
List defaultAllowedSignatureTypes = new ArrayList<>();
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_BIOMETRY);
defaultAllowedSignatureTypes.add(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY);
return this.validateToken(tokenHeader, defaultAllowedSignatureTypes);
}
/**
* Extract request body bytes from HTTP servlet request. In case the data was transparently decrypted, use the decrypted request data.
* @param servletRequest HTTP servlet request.
* @return Request body bytes.
* @throws PowerAuthAuthenticationException In case request body is invalid.
*/
public @Nullable byte[] extractRequestBodyBytes(@Nonnull HttpServletRequest servletRequest) throws PowerAuthAuthenticationException {
if (servletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT) != null) {
// Implementation of sign-then-encrypt - in case the encryption object is present and signature is validate, use decrypted request data
PowerAuthEciesEncryption eciesEncryption = (PowerAuthEciesEncryption) servletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT);
return eciesEncryption.getDecryptedRequest();
} else {
// Request data was not encrypted - use regular PowerAuth request body for signature validation
PowerAuthRequestBody requestBody = ((PowerAuthRequestBody) servletRequest.getAttribute(PowerAuthRequestObjects.REQUEST_BODY));
if (requestBody == null) {
logger.warn("The X-PowerAuth-Request-Body request attribute is missing. Register the PowerAuthRequestFilter to fix this error.");
throw new PowerAuthRequestFilterException();
}
return requestBody.getRequestBytes();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy