我正在尝试在 quarkus 中进行一些 websocket 身份验证。我目前有使用启用身份验证的 Rest 端点。我使用 keyclock 进行身份验证,并使用 vert.x 与 websocket 进行双向连接
@Path("/hello")
"@Authenticated"
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from RESTEasy Reactive";
}
}
我有服装租户解析器。因为这是多租户应用程序。
这是我的 application.property 文件。
quarkus.oidc.tenant-enabled=false
quarkus.oidc.client-id=telemetry-service
(我使用此默认租户未启用。因为这是多租户应用程序。我使用客户租户解析器。但未包含在此处。因为我不想使这个问题复杂化。我将如何添加问题的结尾.谢谢..)
问题是我有 Bearer 令牌,我也将它发送到 websocket 端点,然后我想使用某种重定向来验证该令牌。我阅读了一些文档。还是很难解决这个问题。问题是我想做“@Authenticated”注释所做的事情。正如我在文档“HttpAuthenticationMechanism”中所理解的那样,提取 Bearer 令牌并将其传递到“IdentityProvider”以验证和创建“SecurityIdentity”。我想我想做的是如何将我的 Bearer 令牌传递给 IdentitiyProvider。有人可以帮我做这件事吗?我必须知道如何在语法上验证 websocket。
自定义租户解析器
@ApplicationScoped
public class CustomTenantResolver implements TenantConfigResolver {
OidcConfig oidcConfig;
ApplicationHttpConfig applicationHttpConfig;
private final UrlHandler urlHandler;
private static final String ORIGIN = "origin";
private static final String REFER_URL = "referer";
private static final String SEC_FETCH_SITE = "sec-Fetch-Site";
public CustomTenantResolver(ApplicationHttpConfig applicationHttpConfig, OidcConfig oidcConfig, UrlHandler urlHandler) {
super();
this.applicationHttpConfig = applicationHttpConfig;
this.oidcConfig = oidcConfig;
this.urlHandler = urlHandler;
}
@Override
public Uni<OidcTenantConfig> resolve(RoutingContext context, OidcRequestContext<OidcTenantConfig> requestContext) {
// get the path and the host
String origin = context.request().getHeader(ORIGIN);
String referUrl = context.request().getHeader(REFER_URL);
String secFetchSite = context.request().getHeader(SEC_FETCH_SITE);
Log.info("reserved origin: " + origin + ", referUrl: " + referUrl + ", sec-fetch-site: " + secFetchSite);
/*
* this is the client id for this service
* this client should create in the relevant keycloak realms and should available appropriate permissions
*/
String clientId = oidcConfig.clientId();
Log.debug("clientId: " + clientId);
if (origin == null && referUrl == null) {
Log.error("Origin and referUrl not available, cannot map to tenant");
return Uni.createFrom().nullItem();
}
String host;
String protocol;
try {
if (origin != null) {
host = urlHandler.getHostFromGivenUrl(origin);
protocol = urlHandler.getProtocolFromGivenUrl(origin);
} else {
host = urlHandler.getHostFromGivenUrl(referUrl);
protocol = urlHandler.getProtocolFromGivenUrl(referUrl);
if (!isInSameOrigin(secFetchSite, host)) {
Log.error("origin not available in the url and also not in the same origin, cannot map to tenant");
return Uni.createFrom().nullItem();
}
}
} catch (MalformedURLException e) {
Log.error("failed to decode the url");
Log.debug(e);
return Uni.createFrom().nullItem();
}
Log.debug("host: " + host + ", protocol: " + protocol);
String[] urlContent = host.split("\\.", 3);
Log.debug("urlParams: " + Arrays.toString(urlContent));
return getTheOidcTenantConfigUniBasedOnURLContent(urlContent, clientId, protocol);
}
private boolean isInSameOrigin(String secFetchSite, String host) {
return (secFetchSite != null && secFetchSite.compareTo("same-origin") == 0) || host.compareTo(applicationHttpConfig.host()) == 0;
}
private Uni<OidcTenantConfig> getTheOidcTenantConfigUniBasedOnURLContent(String[] urlContent, String clientId, String protocol) {
if (urlContent.length == 3) {
String keycloakUrl = getKeycloakUrl(protocol, urlContent[2]);
Log.debug("keycloak URL: " + keycloakUrl);
Log.info("found the matching tenant");
return getOidcTenantConfigUni(keycloakUrl, urlContent[0], clientId);
} else {
Log.info("url don't have required content to decide the realm, " +
"cannot match with given url patterns, cannot map to tenant");
return Uni.createFrom().nullItem();
}
}
private String getKeycloakUrl(String protocol, String host) {
return protocol + "://idp." + host;
}
private Uni<OidcTenantConfig> getOidcTenantConfigUni(String keycloakUrl, String tenantId, String clientId) {
OidcTenantConfig config = new OidcTenantConfig();
config.setTenantId(tenantId);
String authServerUrl = keycloakUrl + "/realms/" + tenantId;
config.setAuthServerUrl(authServerUrl);
Log.info("redirected to: " + authServerUrl);
config.setClientId(clientId);
config.setApplicationType(OidcTenantConfig.ApplicationType.SERVICE);
return Uni.createFrom().item(config);
}
}