Search in sources :

Example 1 with BasicAuthValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO in project carbon-apimgt by wso2.

the class BasicAuthCredentialValidator method convertToDTO.

private BasicAuthValidationInfoDTO convertToDTO(org.wso2.carbon.apimgt.impl.dto.xsd.BasicAuthValidationInfoDTO generatedDto) {
    BasicAuthValidationInfoDTO dto = new BasicAuthValidationInfoDTO();
    dto.setAuthenticated(generatedDto.getAuthenticated());
    dto.setHashedPassword(generatedDto.getHashedPassword());
    dto.setDomainQualifiedUsername(generatedDto.getDomainQualifiedUsername());
    dto.setUserRoleList(generatedDto.getUserRoleList());
    return dto;
}
Also used : BasicAuthValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO)

Example 2 with BasicAuthValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO in project carbon-apimgt by wso2.

the class BasicAuthCredentialValidator method validateScopes.

/**
 * Validates the roles of the given user against the roles of the scopes of the API resource.
 *
 * @param username     given username
 * @param openAPI      OpenAPI of the API
 * @param synCtx       The message to be authenticated
 * @param userRoleList The list of roles of the user
 * @return true if the validation passed
 * @throws APISecurityException If an authentication failure or some other error occurs
 */
@MethodStats
public boolean validateScopes(String username, OpenAPI openAPI, MessageContext synCtx, BasicAuthValidationInfoDTO basicAuthValidationInfoDTO) throws APISecurityException {
    String[] userRoleList = basicAuthValidationInfoDTO.getUserRoleList();
    String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
    String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
    String apiElectedResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
    String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
    String httpMethod = (String) axis2MessageContext.getProperty(APIConstants.DigestAuthConstants.HTTP_METHOD);
    String resourceKey = apiContext + ":" + apiVersion + ":" + apiElectedResource + ":" + httpMethod;
    Map<String, Scope> scopeMap = apiKeyValidator.retrieveScopes(tenantDomain);
    String resourceCacheKey = resourceKey + ":" + username;
    if (gatewayKeyCacheEnabled && getGatewayBasicAuthResourceCache().get(resourceCacheKey) != null && basicAuthValidationInfoDTO.isCached()) {
        return true;
    }
    if (openAPI != null) {
        // retrieve the user roles related to the scope of the API resource
        List<String> resourceScopes = OpenAPIUtils.getScopesOfResource(openAPI, synCtx);
        if (resourceScopes != null && resourceScopes.size() > 0) {
            for (String resourceScope : resourceScopes) {
                Scope scope = scopeMap.get(resourceScope);
                if (scope != null) {
                    if (scope.getRoles().isEmpty()) {
                        log.debug("Scope " + resourceScope + " didn't have roles");
                        if (gatewayKeyCacheEnabled) {
                            getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
                        }
                        return true;
                    } else {
                        // any of the role of the user
                        if (validateInternalUserRoles(scope.getRoles(), userRoleList)) {
                            if (gatewayKeyCacheEnabled) {
                                getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
                            }
                            return true;
                        }
                        // check if the roles related to the API resource contains any of the role of the user
                        for (String role : userRoleList) {
                            if (scope.getRoles().contains(role)) {
                                if (gatewayKeyCacheEnabled) {
                                    getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
                                }
                                return true;
                            }
                        }
                    }
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Basic Authentication: No scopes for the API resource: ".concat(resourceKey));
            }
            return true;
        }
    } else if (APIConstants.GRAPHQL_API.equals(synCtx.getProperty(APIConstants.API_TYPE))) {
        HashMap<String, String> operationScopeMappingList = (HashMap<String, String>) synCtx.getProperty(APIConstants.SCOPE_OPERATION_MAPPING);
        String[] operationList = ((String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE)).split(",");
        for (String operation : operationList) {
            String operationScope = operationScopeMappingList.get(operation);
            if (operationScope != null) {
                if (scopeMap.containsKey(operationScope)) {
                    List<String> operationRoles = scopeMap.get(operationScope).getRoles();
                    boolean userHasOperationRole = false;
                    if (operationRoles.isEmpty()) {
                        userHasOperationRole = true;
                    } else {
                        for (String role : userRoleList) {
                            if (operationRoles.contains(role)) {
                                userHasOperationRole = true;
                                break;
                            }
                        }
                    }
                    if (!userHasOperationRole) {
                        throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, "Scope validation failed");
                    }
                } else {
                    throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
                }
            }
        }
        if (gatewayKeyCacheEnabled) {
            getGatewayBasicAuthResourceCache().put(resourceCacheKey, resourceKey);
        }
        return true;
    } else {
        if (log.isDebugEnabled()) {
            log.debug("Basic Authentication: No OpenAPI found in the gateway for the API: ".concat(apiContext).concat(":").concat(apiVersion));
        }
        return true;
    }
    if (log.isDebugEnabled()) {
        log.debug("Basic Authentication: Scope validation failed for the API resource: ".concat(apiElectedResource));
    }
    throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, "Scope validation failed");
}
Also used : APISecurityException(org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException) Scope(org.wso2.carbon.apimgt.keymgt.model.entity.Scope) HashMap(java.util.HashMap) List(java.util.List) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) MethodStats(org.wso2.carbon.apimgt.gateway.MethodStats)

Example 3 with BasicAuthValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO in project carbon-apimgt by wso2.

the class BasicAuthCredentialValidator method validate.

/**
 * Validates the given username and password against the users in the user store.
 *
 * @param username given username
 * @param password given password
 * @return true if the validation passed
 * @throws APISecurityException If an authentication failure or some other error occurs
 */
@MethodStats
public BasicAuthValidationInfoDTO validate(String username, String password) throws APISecurityException {
    boolean isAuthenticated;
    String cachedPasswordHash = null;
    String providedPasswordHash = null;
    String invalidCachedPasswordHash;
    if (gatewayKeyCacheEnabled) {
        providedPasswordHash = GatewayUtils.hashString(password.getBytes(StandardCharsets.UTF_8));
        BasicAuthValidationInfoDTO cachedValidationInfoObj = (BasicAuthValidationInfoDTO) getGatewayUsernameCache().get(username);
        if (cachedValidationInfoObj != null) {
            cachedPasswordHash = cachedValidationInfoObj.getHashedPassword();
            cachedValidationInfoObj.setCached(true);
        }
        if (cachedPasswordHash != null && cachedPasswordHash.equals(providedPasswordHash)) {
            log.debug("Basic Authentication: <Valid Username Cache> Username & password authenticated");
            return cachedValidationInfoObj;
        } else {
            BasicAuthValidationInfoDTO invalidCacheValidationInfoObj = (BasicAuthValidationInfoDTO) getInvalidUsernameCache().get(username);
            if (invalidCacheValidationInfoObj != null) {
                invalidCacheValidationInfoObj.setCached(true);
                invalidCachedPasswordHash = invalidCacheValidationInfoObj.getHashedPassword();
                if (invalidCachedPasswordHash != null && invalidCachedPasswordHash.equals(providedPasswordHash)) {
                    log.debug("Basic Authentication: <Invalid Username Cache> Username & password authentication failed");
                    invalidCacheValidationInfoObj.setAuthenticated(// If (username->password) is in the invalid cache
                    false);
                    return invalidCacheValidationInfoObj;
                }
            }
        }
    }
    BasicAuthValidationInfoDTO basicAuthValidationInfoDTO;
    try {
        org.wso2.carbon.apimgt.impl.dto.xsd.BasicAuthValidationInfoDTO generatedInfoDTO = apiKeyMgtRemoteUserStoreMgtServiceStub.getUserAuthenticationInfo(username, password);
        basicAuthValidationInfoDTO = convertToDTO(generatedInfoDTO);
        isAuthenticated = basicAuthValidationInfoDTO.isAuthenticated();
    } catch (APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException | RemoteException e) {
        log.error("Basic Authentication: Error while accessing backend services to validate user authentication for user : " + username);
        throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, e.getMessage(), e);
    }
    if (gatewayKeyCacheEnabled) {
        basicAuthValidationInfoDTO.setHashedPassword(providedPasswordHash);
        if (isAuthenticated) {
            // put (username->password) into the valid cache
            getGatewayUsernameCache().put(username, basicAuthValidationInfoDTO);
        } else {
            // put (username->password) into the invalid cache
            getInvalidUsernameCache().put(username, basicAuthValidationInfoDTO);
        }
    }
    return basicAuthValidationInfoDTO;
}
Also used : APISecurityException(org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException) BasicAuthValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO) RemoteException(java.rmi.RemoteException) APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException(org.wso2.carbon.apimgt.keymgt.stub.usermanager.APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException) MethodStats(org.wso2.carbon.apimgt.gateway.MethodStats)

Example 4 with BasicAuthValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO in project carbon-apimgt by wso2.

the class BasicAuthAuthenticatorTest method setup.

@Before
public void setup() throws Exception {
    PowerMockito.mockStatic(OpenAPIUtils.class);
    PowerMockito.when(OpenAPIUtils.getResourceAuthenticationScheme(Mockito.any(), Mockito.any())).thenReturn(APIConstants.AUTH_APPLICATION_OR_USER_LEVEL_TOKEN);
    messageContext = Mockito.mock(Axis2MessageContext.class);
    axis2MsgCntxt = Mockito.mock(org.apache.axis2.context.MessageContext.class);
    Mockito.when(axis2MsgCntxt.getProperty(APIMgtGatewayConstants.REQUEST_RECEIVED_TIME)).thenReturn("1506576365");
    Mockito.when(((Axis2MessageContext) messageContext).getAxis2MessageContext()).thenReturn(axis2MsgCntxt);
    Mockito.when((messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT))).thenReturn(Mockito.mock(OpenAPI.class));
    basicAuthAuthenticator = new BasicAuthAuthenticator(CUSTOM_AUTH_HEADER, true, UNLIMITED_THROTTLE_POLICY);
    BasicAuthCredentialValidator basicAuthCredentialValidator = Mockito.mock(BasicAuthCredentialValidator.class);
    BasicAuthValidationInfoDTO basicAuthValidationInfoDTO = new BasicAuthValidationInfoDTO();
    Mockito.when(basicAuthCredentialValidator.validate(Mockito.anyString(), Mockito.anyString())).thenAnswer(invocationOnMock -> {
        Object argument1 = invocationOnMock.getArguments()[0];
        Object argument2 = invocationOnMock.getArguments()[1];
        if ((argument1.equals("test_username@carbon.super") || argument1.equals("test_username_blocked@carbon.super")) && argument2.equals("test_password")) {
            basicAuthValidationInfoDTO.setAuthenticated(true);
            basicAuthValidationInfoDTO.setHashedPassword("hashed_test_password");
            if ("test_username@carbon.super".equals(argument1)) {
                basicAuthValidationInfoDTO.setDomainQualifiedUsername("test_username@carbon.super");
            } else if ("test_username_blocked@carbon.super".equals(argument1)) {
                basicAuthValidationInfoDTO.setDomainQualifiedUsername("test_username_blocked@carbon.super");
            }
            String[] userRoleList = { "roleQ", "roleX" };
            basicAuthValidationInfoDTO.setUserRoleList(userRoleList);
            return basicAuthValidationInfoDTO;
        }
        return basicAuthValidationInfoDTO;
    });
    Mockito.when(basicAuthCredentialValidator.validateScopes(Mockito.anyString(), Mockito.any(OpenAPI.class), Mockito.any(MessageContext.class), Mockito.anyObject())).thenAnswer(invocationOnMock -> {
        Object argument = invocationOnMock.getArguments()[0];
        if (argument.equals("test_username@carbon.super")) {
            return true;
        } else if (argument.equals("test_username_blocked@carbon.super")) {
            throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, "Scope validation failed");
        }
        return false;
    });
    PowerMockito.whenNew(BasicAuthCredentialValidator.class).withNoArguments().thenReturn(basicAuthCredentialValidator);
    Mockito.when(messageContext.getProperty(BasicAuthAuthenticator.PUBLISHER_TENANT_DOMAIN)).thenReturn("carbon.super");
}
Also used : APISecurityException(org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException) BasicAuthValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO) MessageContext(org.apache.synapse.MessageContext) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext) Before(org.junit.Before)

Example 5 with BasicAuthValidationInfoDTO

use of org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO in project carbon-apimgt by wso2.

the class CacheInvalidationServiceImpl method invalidateCachedUsernames.

@Override
public void invalidateCachedUsernames(String[] usernameList) {
    if (usernameList == null || usernameList.length == 0) {
        log.debug("No username received to invalidate Gateway Username Cache.");
        return;
    }
    Map<String, Set<String>> tenantDomainMap = new HashMap<>();
    for (String username : usernameList) {
        String tenantDomain = MultitenantUtils.getTenantDomain(username);
        Set<String> usersInTenant = tenantDomainMap.get(tenantDomain);
        if (usersInTenant == null) {
            usersInTenant = new HashSet<>();
        }
        usersInTenant.add(username);
        tenantDomainMap.put(tenantDomain, usersInTenant);
    }
    for (Map.Entry<String, Set<String>> tenantEntry : tenantDomainMap.entrySet()) {
        boolean startTenantFlow = false;
        try {
            startTenantFlow = startTenantFlow(tenantEntry.getKey());
            Cache gatewayUsernameCache = CacheProvider.getGatewayUsernameCache();
            Cache gatewayInvalidUsernameCache = CacheProvider.getInvalidUsernameCache();
            for (String username : tenantEntry.getValue()) {
                if (gatewayUsernameCache != null) {
                    gatewayUsernameCache.remove(username);
                }
                if (gatewayInvalidUsernameCache != null) {
                    BasicAuthValidationInfoDTO basicAuthValidationInfoDTO = new BasicAuthValidationInfoDTO();
                    basicAuthValidationInfoDTO.setAuthenticated(false);
                    basicAuthValidationInfoDTO.setDomainQualifiedUsername(username);
                    gatewayInvalidUsernameCache.put(username, basicAuthValidationInfoDTO);
                }
            }
        } finally {
            if (startTenantFlow) {
                endTenantFlow();
            }
        }
    }
}
Also used : BasicAuthValidationInfoDTO(org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO) Set(java.util.Set) HashSet(java.util.HashSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) Cache(javax.cache.Cache)

Aggregations

BasicAuthValidationInfoDTO (org.wso2.carbon.apimgt.impl.dto.BasicAuthValidationInfoDTO)6 APISecurityException (org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException)4 HashMap (java.util.HashMap)3 Axis2MessageContext (org.apache.synapse.core.axis2.Axis2MessageContext)3 MethodStats (org.wso2.carbon.apimgt.gateway.MethodStats)3 OpenAPI (io.swagger.v3.oas.models.OpenAPI)1 RemoteException (java.rmi.RemoteException)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Cache (javax.cache.Cache)1 MessageContext (org.apache.synapse.MessageContext)1 Before (org.junit.Before)1 AuthenticationContext (org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext)1 AuthenticationResponse (org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationResponse)1 VerbInfoDTO (org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO)1 Scope (org.wso2.carbon.apimgt.keymgt.model.entity.Scope)1 APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException (org.wso2.carbon.apimgt.keymgt.stub.usermanager.APIKeyMgtRemoteUserStoreMgtServiceAPIManagementException)1