Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle introspection for SaaS app tenant users. #124

Merged
merged 3 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.is.key.manager.tokenpersistence.dao.DBInvalidTokenPersistence;
import org.wso2.is.key.manager.tokenpersistence.model.InvalidTokenPersistenceService;
import org.wso2.is.notification.NotificationEventSenderService;

/**
* Holder class to hold service references used in non-token persistence.
Expand All @@ -32,6 +33,7 @@ public class ServiceReferenceHolder {
private RealmService realmService;
private InvalidTokenPersistenceService tokenPersistenceService;
private AccessTokenDAO migratedAccessTokenDAO;
private NotificationEventSenderService eventSenderService;

private ServiceReferenceHolder() {

Expand Down Expand Up @@ -78,4 +80,14 @@ public void setMigratedAccessTokenDAO(AccessTokenDAO migratedAccessTokenDAO) {

this.migratedAccessTokenDAO = migratedAccessTokenDAO;
}

public NotificationEventSenderService getEventSenderService() {

return eventSenderService;
}

public void setEventSenderService(NotificationEventSenderService eventSenderService) {

this.eventSenderService = eventSenderService;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.wso2.is.key.manager.tokenpersistence.processor.InMemoryOAuth2RevocationProcessor;
import org.wso2.is.key.manager.tokenpersistence.processor.InMemoryRefreshTokenGrantProcessor;
import org.wso2.is.key.manager.tokenpersistence.processor.InMemoryTokenProvider;
import org.wso2.is.notification.NotificationEventSenderService;

/**
* KeyManager persistence component to handle non-token persistence.
Expand Down Expand Up @@ -110,4 +111,23 @@ protected void unsetIdentityCoreInitializedEventService(IdentityCoreInitializedE
/* reference IdentityCoreInitializedEvent service to guarantee that this component will wait until identity core
is started */
}

@Reference(
name = "wso2.is.notification.service",
service = org.wso2.is.notification.NotificationEventSenderService.class,
cardinality = ReferenceCardinality.MANDATORY,
policy = ReferencePolicy.DYNAMIC,
unbind = "unsetNotificationEventSenderService")
protected void setNotificationEventSenderService(NotificationEventSenderService eventSenderService) {

if (eventSenderService != null && log.isDebugEnabled()) {
log.debug("Notification Event Sender Service initialized");
}
ServiceReferenceHolder.getInstance().setEventSenderService(eventSenderService);
}

protected void unsetNotificationEventSenderService(NotificationEventSenderService eventSenderService) {

ServiceReferenceHolder.getInstance().setEventSenderService(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.is.key.manager.tokenpersistence.internal.ServiceReferenceHolder;
import org.wso2.is.notification.event.ConsumerAppRevocationEvent;
import org.wso2.is.notification.internal.ServiceReferenceHolder;

import java.util.Calendar;
import java.util.Properties;
Expand Down Expand Up @@ -91,7 +91,7 @@ public void doPostTokenRevocationOnClientAppEvent(String consumerKey, Properties
log.error("Error while finding tenant id", e);
}
consumerAppRevocationEvent.setRevocationTime(revocationTime);
ServiceReferenceHolder.getInstance().getEventSender().publishEvent(consumerAppRevocationEvent);
ServiceReferenceHolder.getInstance().getEventSenderService().publishEvent(consumerAppRevocationEvent);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,11 @@ public static AuthenticatedUser getAuthenticatedUser(JWTClaimsSet claimsSet) thr
throw new IdentityOAuth2Exception("Error while getting tenant domain from OAuth app with consumer key: "
+ consumerKey);
}
authenticatedUser = resolveAuthenticatedUserFromEntityId((String)
claimsSet.getClaim(OAuth2Constants.ENTITY_ID), consumerAppTenantDomain);
if (claimsSet.getClaim(OAuth2Constants.IS_FEDERATED) != null
&& (boolean) claimsSet.getClaim(OAuth2Constants.IS_FEDERATED)) {
boolean isFederated = claimsSet.getClaim(OAuth2Constants.IS_FEDERATED) != null
&& (boolean) claimsSet.getClaim(OAuth2Constants.IS_FEDERATED);
authenticatedUser = resolveAuthenticatedUserFromEntityId((String) claimsSet.getClaim(OAuth2Constants.ENTITY_ID),
consumerAppTenantDomain, isFederated, claimsSet.getSubject());
if (isFederated) {
if (authenticatedUser == null) {
authenticatedUser =
createFederatedAuthenticatedUser((String) claimsSet.getClaim(OAuth2Constants.ENTITY_ID));
Expand All @@ -219,11 +220,15 @@ public static AuthenticatedUser getAuthenticatedUser(JWTClaimsSet claimsSet) thr
*
* @param entityId Entity ID JWT Claim value which uniquely identifies the subject principle of the JWT. Eg: user
* @param consumerAppTenantDomain Tenant domain of the consumer app from the token
* @param isFederated Federated user token
* @param sub Subject claim
* @return Username
* @throws IdentityOAuth2Exception If an error occurs while getting the authenticated user
*/
private static AuthenticatedUser resolveAuthenticatedUserFromEntityId(String entityId,
String consumerAppTenantDomain)
String consumerAppTenantDomain,
boolean isFederated,
String sub)
throws IdentityOAuth2Exception {

AuthenticatedUser authenticatedUser = null;
Expand All @@ -234,14 +239,20 @@ private static AuthenticatedUser resolveAuthenticatedUserFromEntityId(String ent
} else {
// Assume entity ID is userId.
try {
String userName = getUserNameFromUserID(entityId, TokenMgtUtil.getTenantDomain());
String userTenantDomain = TokenMgtUtil.getTenantDomain();
String userName = getUserNameFromUserID(entityId, userTenantDomain);
if (StringUtils.isBlank(userName)) {
// if service url is not a tenant aware url, we need to get the tenant domain from the token.
userName = getUserNameFromUserID(entityId, consumerAppTenantDomain);
userTenantDomain = consumerAppTenantDomain;
userName = getUserNameFromUserID(entityId, userTenantDomain);
}
if (StringUtils.isNotBlank(userName)) {
authenticatedUser = OAuth2Util.getUserFromUserName(userName);
authenticatedUser.setTenantDomain(TokenMgtUtil.getTenantDomain());
authenticatedUser.setTenantDomain(userTenantDomain);
authenticatedUser.setUserId(entityId);
} else if (!isFederated && !StringUtils.isBlank(sub)) {
userName = sub; // assume sub is a full qualified username
authenticatedUser = OAuth2Util.getUserFromUserName(userName);
authenticatedUser.setUserId(entityId);
}
} catch (UserStoreException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
/**
* Utility class to push events.
*/
public class EventSender {
public class EventSender implements NotificationEventSenderService {

private static final Log log = LogFactory.getLog(EventSender.class);
private String notificationEndpoint;
Expand All @@ -68,6 +68,7 @@ public EventSender(String notificationEndpoint, Map<String, String> headers) {
this.headers = headers;
}

@Override
public void publishEvent(Event event) {

EventRunner eventRunner =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.is.notification;

import org.wso2.is.notification.event.Event;

/**
* Interface for publishing wso2 is notification event service.
*/
public interface NotificationEventSenderService {

void publishEvent(Event event);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.ConfigurationContextService;
import org.wso2.is.notification.EventSender;
import org.wso2.is.notification.NotificationEventSenderService;

/**
* Holder class to hold service references used in notification.
Expand All @@ -12,7 +12,7 @@ public class ServiceReferenceHolder {
private static final ServiceReferenceHolder instance = new ServiceReferenceHolder();
private RealmService realmService;
private ConfigurationContextService contextService;
private EventSender eventSender;
private NotificationEventSenderService eventSender;

public static ServiceReferenceHolder getInstance() {

Expand Down Expand Up @@ -40,11 +40,11 @@ public void setContextService(ConfigurationContextService contextService) {
this.contextService = contextService;
}

public EventSender getEventSender() {
public NotificationEventSenderService getEventSender() {
return eventSender;
}

public void setEventSender(EventSender eventSender) {
public void setEventSender(NotificationEventSenderService eventSender) {
this.eventSender = eventSender;
}
}