use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class SettingsMappingUtil method GetScopeList.
private List<String> GetScopeList() throws APIManagementException {
String definition = null;
try {
definition = IOUtils.toString(RestApiUtil.class.getResourceAsStream("/devportal-api.yaml"), "UTF-8");
} catch (IOException e) {
log.error("Error while reading the swagger definition", e);
}
APIDefinition oasParser = OASParserUtil.getOASParser(definition);
Set<Scope> scopeSet = oasParser.getScopes(definition);
List<String> scopeList = new ArrayList<>();
for (Scope entry : scopeSet) {
scopeList.add(entry.getKey());
}
return scopeList;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class OAuthJwtAuthenticatorImpl method handleScopeValidation.
/**
* Handle scope validation
*
* @param accessToken JWT token
* @param signedJWTInfo : Signed token info
* @param message : cxf Message
*/
private boolean handleScopeValidation(Message message, SignedJWTInfo signedJWTInfo, String accessToken) throws APIManagementException, ParseException {
String maskedToken = message.get(RestApiConstants.MASKED_TOKEN).toString();
OAuthTokenInfo oauthTokenInfo = new OAuthTokenInfo();
oauthTokenInfo.setAccessToken(accessToken);
oauthTokenInfo.setEndUserName(signedJWTInfo.getJwtClaimsSet().getSubject());
String scopeClaim = signedJWTInfo.getJwtClaimsSet().getStringClaim(JwtTokenConstants.SCOPE);
if (scopeClaim != null) {
String orgId = RestApiUtil.resolveOrganization(message);
String[] scopes = scopeClaim.split(JwtTokenConstants.SCOPE_DELIMITER);
scopes = java.util.Arrays.stream(scopes).filter(s -> s.contains(orgId)).map(s -> s.replace(APIConstants.URN_CHOREO + orgId + ":", "")).toArray(size -> new String[size]);
oauthTokenInfo.setScopes(scopes);
if (validateScopes(message, oauthTokenInfo)) {
// Add the user scopes list extracted from token to the cxf message
message.getExchange().put(RestApiConstants.USER_REST_API_SCOPES, oauthTokenInfo.getScopes());
// If scope validation successful then set tenant name and user name to current context
String tenantDomain = MultitenantUtils.getTenantDomain(oauthTokenInfo.getEndUserName());
int tenantId;
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
RealmService realmService = (RealmService) carbonContext.getOSGiService(RealmService.class, null);
try {
String username = oauthTokenInfo.getEndUserName();
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
// when the username is an email in supertenant, it has at least 2 occurrences of '@'
long count = username.chars().filter(ch -> ch == '@').count();
// in the case of email, there will be more than one '@'
boolean isEmailUsernameEnabled = Boolean.parseBoolean(CarbonUtils.getServerConfiguration().getFirstProperty("EnableEmailUserName"));
if (isEmailUsernameEnabled || (username.endsWith(SUPER_TENANT_SUFFIX) && count <= 1)) {
username = MultitenantUtils.getTenantAwareUsername(username);
}
}
if (log.isDebugEnabled()) {
log.debug("username = " + username + "masked token " + maskedToken);
}
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
carbonContext.setTenantDomain(tenantDomain);
carbonContext.setTenantId(tenantId);
carbonContext.setUsername(username);
message.put(RestApiConstants.SUB_ORGANIZATION, orgId);
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
APIUtil.loadTenantConfigBlockingMode(tenantDomain);
}
return true;
} catch (UserStoreException e) {
log.error("Error while retrieving tenant id for tenant domain: " + tenantDomain, e);
}
log.debug("Scope validation success for the token " + maskedToken);
return true;
}
log.error("scopes validation failed for the token" + maskedToken);
return false;
}
log.error("scopes validation failed for the token" + maskedToken);
return false;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class OAuthOpaqueAuthenticatorImpl method authenticate.
/**
* @param message cxf message to be authenticated
* @return true if authentication was successful else false
* @throws APIManagementException when error in authentication process
*/
@Override
public boolean authenticate(Message message) throws APIManagementException {
boolean retrievedFromInvalidTokenCache = false;
boolean retrievedFromTokenCache = false;
String accessToken = RestApiUtil.extractOAuthAccessTokenFromMessage(message, RestApiConstants.REGEX_BEARER_PATTERN, RestApiConstants.AUTH_HEADER_NAME);
OAuthTokenInfo tokenInfo = null;
RESTAPICacheConfiguration cacheConfiguration = APIUtil.getRESTAPICacheConfig();
// validate the token from cache if it is enabled
if (cacheConfiguration.isTokenCacheEnabled()) {
tokenInfo = (OAuthTokenInfo) getRESTAPITokenCache().get(accessToken);
if (tokenInfo != null) {
if (isAccessTokenExpired(tokenInfo)) {
tokenInfo.setTokenValid(false);
// remove the token from token cache and put the token into invalid token cache
// when the access token is expired
getRESTAPIInvalidTokenCache().put(accessToken, tokenInfo);
getRESTAPITokenCache().remove(accessToken);
log.error(RestApiConstants.ERROR_TOKEN_EXPIRED);
return false;
} else {
retrievedFromTokenCache = true;
}
} else {
// if the token doesn't exist in the valid token cache, then check it in the invalid token cache
tokenInfo = (OAuthTokenInfo) getRESTAPIInvalidTokenCache().get(accessToken);
if (tokenInfo != null) {
retrievedFromInvalidTokenCache = true;
}
}
}
// if the tokenInfo is null, then only retrieve the token information from the database
try {
if (tokenInfo == null) {
tokenInfo = getTokenMetaData(accessToken);
}
} catch (APIManagementException e) {
log.error("Error while retrieving token information for token: " + accessToken, e);
}
// if we got valid access token we will proceed with next
if (tokenInfo != null && tokenInfo.isTokenValid()) {
if (cacheConfiguration.isTokenCacheEnabled() && !retrievedFromTokenCache) {
// put the token info into token cache
getRESTAPITokenCache().put(accessToken, tokenInfo);
}
// If access token is valid then we will perform scope check for given resource.
if (validateScopes(message, tokenInfo)) {
// Add the user scopes list extracted from token to the cxf message
message.getExchange().put(RestApiConstants.USER_REST_API_SCOPES, tokenInfo.getScopes());
// If scope validation successful then set tenant name and user name to current context
String tenantDomain = MultitenantUtils.getTenantDomain(tokenInfo.getEndUserName());
int tenantId;
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
RealmService realmService = (RealmService) carbonContext.getOSGiService(RealmService.class, null);
try {
String username = tokenInfo.getEndUserName();
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
// when the username is an email in supertenant, it has at least 2 occurrences of '@'
long count = username.chars().filter(ch -> ch == '@').count();
// in the case of email, there will be more than one '@'
boolean isEmailUsernameEnabled = Boolean.parseBoolean(CarbonUtils.getServerConfiguration().getFirstProperty("EnableEmailUserName"));
if (isEmailUsernameEnabled || (username.endsWith(SUPER_TENANT_SUFFIX) && count <= 1)) {
username = MultitenantUtils.getTenantAwareUsername(username);
}
}
if (log.isDebugEnabled()) {
log.debug("username = " + username);
}
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
carbonContext.setTenantDomain(tenantDomain);
carbonContext.setTenantId(tenantId);
carbonContext.setUsername(username);
message.put(RestApiConstants.SUB_ORGANIZATION, tenantDomain);
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
APIUtil.loadTenantConfigBlockingMode(tenantDomain);
}
return true;
} catch (UserStoreException e) {
log.error("Error while retrieving tenant id for tenant domain: " + tenantDomain, e);
}
} else {
log.error(RestApiConstants.ERROR_SCOPE_VALIDATION_FAILED);
}
} else {
log.error(RestApiConstants.ERROR_TOKEN_INVALID);
if (cacheConfiguration.isTokenCacheEnabled() && !retrievedFromInvalidTokenCache) {
getRESTAPIInvalidTokenCache().put(accessToken, tokenInfo);
}
}
return false;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class SubscriberRegistrationInterceptor method handleMessage.
/**
* Handles the incoming message after post authentication. Only used in Store REST API, to register a newly
* signed up store user who hasn't logged in to Store for the first time either via REST API or Store UI.
* This method will register the user as a subscriber
* (register in AM_SUBSCRIBER table, add the default application for subscriber etc.).
*
* @param message cxf message
*/
@Override
@MethodStats
public void handleMessage(Message message) {
String username = RestApiCommonUtil.getLoggedInUsername();
// by-passes the interceptor if user is an annonymous user
if (username.equalsIgnoreCase(APIConstants.WSO2_ANONYMOUS_USER)) {
return;
}
// checking if the subscriber exists in the subscriber cache
Cache<String, Subscriber> subscriberCache = Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER).getCache(APIConstants.API_SUBSCRIBER_CACHE);
if (subscriberCache.get(username) != null) {
return;
}
// check the existence in the database
String groupId = RestApiUtil.getLoggedInUserGroupId();
String tenantDomain = RestApiCommonUtil.getLoggedInUserTenantDomain();
try {
// takes a consumer object using the user set in thread local carbon context
APIConsumer apiConsumer = RestApiCommonUtil.getLoggedInUserConsumer();
Subscriber subscriber = apiConsumer.getSubscriber(username);
if (subscriber == null) {
synchronized ((username + LOCK_POSTFIX).intern()) {
subscriber = apiConsumer.getSubscriber(username);
if (subscriber == null) {
message.getExchange().get(RestApiConstants.USER_REST_API_SCOPES);
if (!hasSubscribeScope(message)) {
// permission. It should be allowed.
if (logger.isDebugEnabled()) {
logger.debug("User " + username + " does not have subscribe scope " + "(" + APIM_SUBSCRIBE_SCOPE + ")");
}
return;
}
if (!APIConstants.SUPER_TENANT_DOMAIN.equalsIgnoreCase(tenantDomain)) {
loadTenantRegistry();
}
apiConsumer.addSubscriber(username, groupId);
// The subscriber object added here is not a complete subscriber object. It will only contain
// username
subscriberCache.put(username, new Subscriber(username));
if (logger.isDebugEnabled()) {
logger.debug("Subscriber " + username + " added to AM_SUBSCRIBER database");
}
}
}
} else {
subscriberCache.put(username, subscriber);
}
} catch (APIManagementException e) {
RestApiUtil.handleInternalServerError("Unable to add the subscriber " + username, e, logger);
}
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class BasicAuthenticationInterceptor method validateUserRolesWithRESTAPIScopes.
/**
* This method validates the user roles against the roles of the REST API scopes defined for the current resource.
*
* @param resourceScopeList Scope list of the current resource
* @param restAPIScopes RESTAPIScopes mapping for the current tenant
* @param userRoles Role list for the user
* @param username Username
* @param path Path Info
* @param verb HTTP Request Method
* @param inMessage cxf Message to set the matched user scopes for the resource
* @return whether user role validation against REST API scope roles is success or not.
*/
private boolean validateUserRolesWithRESTAPIScopes(List<Scope> resourceScopeList, Map<String, String> restAPIScopes, String[] userRoles, String username, String path, String verb, Message inMessage) {
// Holds the REST API scope list which the user will get successfully validated against with
List<Scope> validatedUserScopes = new ArrayList<>();
// iterate the non empty scope list of the URITemplate of the invoking resource
for (Scope scope : resourceScopeList) {
// get the configured roles list string of the requested resource
String resourceRolesString = restAPIScopes.get(scope.getKey());
if (StringUtils.isNotBlank(resourceRolesString)) {
// split role list string read using comma separator
List<String> resourceRoleList = Arrays.asList(resourceRolesString.split("\\s*,\\s*"));
// check if the roles related to the API resource contains any of the role of the user
for (String role : userRoles) {
if (resourceRoleList.contains(role)) {
// Role validation is success. Add the current scope to the validated user scope list and
// skip role check iteration of current scope and move to next resource scope.
validatedUserScopes.add(scope);
if (log.isDebugEnabled()) {
log.debug("Basic Authentication: role validation successful for user: " + username + " with scope: " + scope.getKey() + " for resource path: " + path + " and verb " + verb);
log.debug("Added scope: " + scope.getKey() + " to validated user scope list");
}
break;
}
}
} else {
// No role for the requested resource scope. Add it to the validated user scope list.
validatedUserScopes.add(scope);
if (log.isDebugEnabled()) {
log.debug("Role validation skipped. No REST API scope to role mapping defined for resource scope: " + scope.getKey() + " Treated as anonymous scope.");
}
}
}
List<String> scopes = new ArrayList<>();
validatedUserScopes.forEach(scope -> scopes.add(scope.getKey()));
// Add the validated user scope list to the cxf message
inMessage.getExchange().put(RestApiConstants.USER_REST_API_SCOPES, scopes.toArray(new String[0]));
if (!validatedUserScopes.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("Successfully validated REST API Scopes for the user " + username);
}
return true;
}
// none of the resource scopes were matched against the user role set
log.error("Insufficient privileges. Role validation failed for user: " + username + " to access resource path: " + path + " and verb " + verb);
return false;
}
Aggregations