Quarkus Keycloak 客户授权

问题描述 投票:0回答:0

我正在尝试在 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);
    }

}
authentication websocket keycloak quarkus vert.x
© www.soinside.com 2019 - 2024. All rights reserved.