无法使用JWT令牌对Kusto客户端进行身份验证。

huangapple go评论73阅读模式
英文:

Unable to authenticate Kusto Client using JWTToken

问题

我们使用Java 8msal4j版本0.6.0-preview。要连接到 Kusto,我们使用 JWT 令牌:

ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadAccessTokenAuthentication(resourceUri, accessToken);
Client kustoClient = ClientFactory.createClient(csb);

createWithAadAccessTokenAuthentication()内部,它调用了这个ConnectionStringBuilder构造函数:

public static ConnectionStringBuilder createWithAadAccessTokenAuthentication(String resourceUri, String token) {
    if (StringUtils.isEmpty(resourceUri)) {
        throw new IllegalArgumentException("resourceUri cannot be null or empty");
    } else if (StringUtils.isEmpty(token)) {
        throw new IllegalArgumentException("token cannot be null or empty");
    } else {
        ConnectionStringBuilder csb = new ConnectionStringBuilder(resourceUri);
        csb.accessToken = token;
        return csb;
    }
}

它将除了clusterUri之外的每个字段都设置为null

private ConnectionStringBuilder(String resourceUri) {
    this.clusterUri = resourceUri;
    this.usernameHint = null;
    this.applicationClientId = null;
    this.applicationKey = null;
    this.aadAuthorityId = null;
    this.x509Certificate = null;
    this.privateKey = null;
    this.accessToken = null;
    this.tokenProvider = null;
}

因此,我们从createClient()方法中得到了一个错误。因为它调用了ClientImpl(csb)hostauth返回null,这会触发这一行的空指针异常:String auth = clusterUri.getAuthority().toLowerCase();

public static Client createClient(ConnectionStringBuilder csb) throws URISyntaxException {
    return new ClientImpl(csb);
}
public ClientImpl(ConnectionStringBuilder csb) throws URISyntaxException {
    String url = csb.getClusterUrl();
    URI clusterUri = new URI(url);
    String host = clusterUri.getHost();
    String auth = clusterUri.getAuthority().toLowerCase();
    if (host == null && auth.endsWith(";fed=true")) {
        url = (new URIBuilder()).setScheme(clusterUri.getScheme()).setHost(auth.substring(0, clusterUri.getAuthority().indexOf(";fed=true"))).toString();
        csb.setClusterUrl(url);
    }

    this.clusterUrl = url;
    this.aadAuthenticationHelper = TokenProviderFactory.createTokenProvider(csb);
    this.clientVersionForTracing = "Kusto.Java.Client";
    String version = Utils.getPackageVersion();
    if (StringUtils.isNotBlank(version)) {
        this.clientVersionForTracing = this.clientVersionForTracing + ":" + version;
    }

    if StringUtils.isNotBlank(csb.getClientVersionForTracing())) {
        this.clientVersionForTracing = this.clientVersionForTracing + "[" + csb.getClientVersionForTracing() + "]";
    }

    this.applicationNameForTracing = csb.getApplicationNameForTracing();
}

这里有什么其他的替代方案?

英文:

We use Java 8 and msal4j version 0.6.0-preview. To connect to Kusto, we use JWT Token:

ConnectionStringBuilder csb = ConnectionStringBuilder.createWithAadAccessTokenAuthentication(resourceUri, accessToken);
Client kustoClient = ClientFactory.createClient(csb);

Inside thencreateWithAadAccessTokenAuthentication(), it is calling this ConnectionStringBuilder constructor:

public static ConnectionStringBuilder createWithAadAccessTokenAuthentication(String resourceUri, String token) {
        if (StringUtils.isEmpty(resourceUri)) {
            throw new IllegalArgumentException("resourceUri cannot be null or empty");
        } else if (StringUtils.isEmpty(token)) {
            throw new IllegalArgumentException("token cannot be null or empty");
        } else {
            ConnectionStringBuilder csb = new ConnectionStringBuilder(resourceUri);
            csb.accessToken = token;
            return csb;
        }
    }

it is setting every field to null except for clusterUri.

private ConnectionStringBuilder(String resourceUri) {
        this.clusterUri = resourceUri;
        this.usernameHint = null;
        this.applicationClientId = null;
        this.applicationKey = null;
        this.aadAuthorityId = null;
        this.x509Certificate = null;
        this.privateKey = null;
        this.accessToken = null;
        this.tokenProvider = null;
    }

Thus we got an error from createClient() method. Because it is calling ClientImpl(csb). host and auth are returning null, which triggers null pointer exception in this line: String auth = clusterUri.getAuthority().toLowerCase();

public static Client createClient(ConnectionStringBuilder csb) throws URISyntaxException {
        return new ClientImpl(csb);
    }

 public ClientImpl(ConnectionStringBuilder csb) throws URISyntaxException {
        String url = csb.getClusterUrl();
        URI clusterUri = new URI(url);
        String host = clusterUri.getHost();
        String auth = clusterUri.getAuthority().toLowerCase();
        if (host == null && auth.endsWith(";fed=true")) {
            url = (new URIBuilder()).setScheme(clusterUri.getScheme()).setHost(auth.substring(0, clusterUri.getAuthority().indexOf(";fed=true"))).toString();
            csb.setClusterUrl(url);
        }

        this.clusterUrl = url;
        this.aadAuthenticationHelper = TokenProviderFactory.createTokenProvider(csb);
        this.clientVersionForTracing = "Kusto.Java.Client";
        String version = Utils.getPackageVersion();
        if (StringUtils.isNotBlank(version)) {
            this.clientVersionForTracing = this.clientVersionForTracing + ":" + version;
        }

        if (StringUtils.isNotBlank(csb.getClientVersionForTracing())) {
            this.clientVersionForTracing = this.clientVersionForTracing + "[" + csb.getClientVersionForTracing() + "]";
        }

        this.applicationNameForTracing = csb.getApplicationNameForTracing();
    }

What are the other alternatives here?

答案1

得分: 1

你正在使用哪个版本的Kusto SDK?
您是否可以使用SDK自身提供的其他AuthN选项,而不是手动获取令牌并将其值传递给SDK?
通常更推荐这种做法(更不容易因令牌过期而导致长时间运行的错误)。

附言:通常在源代码的存储库中报告此类问题是常见的。 无法使用JWT令牌对Kusto客户端进行身份验证。
https://github.com/Azure/azure-kusto-java/issues

英文:

Which version of the Kusto SDK are you using?
Can you use any of the other AuthN options provided by the SDK itself, instead of acquiring the token manually and passing it's value to the SDK?
It's generally more recommanded (less prone to long running errors due to token expiration)

P.S. It common to report such issues in the repo for the source code. 无法使用JWT令牌对Kusto客户端进行身份验证。
https://github.com/Azure/azure-kusto-java/issues

答案2

得分: 1

我们在面对面交谈后发现问题出在resourceUri参数中传递的值,而这个参数期望的是集群的URL("https://cluster.region.kusto.windows.net"),而提供的URI是ARM资源的URI,因此在调用new URI()时未解析URL的主机和身份验证部分。

英文:

After talking F2F we found the issue is with the value passed in the resourceUri param, while this expects a url of the cluster ("https://cluster.region.kusto.windows.net") the provided uri was the ARM resource uri hence no host and no auth sections of the URL were parsed by the call to new URI().

huangapple
  • 本文由 发表于 2023年6月13日 07:33:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定