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

Version 6.2: "com.microsoft.graph.models.odataerrors.ODataError: The value for the property "usage" in one of your credentials is invalid. Acceptable values are Sign, Verify." when graphClient.applications().byApplicationId("<my app id>") .patch(app) if try to add a new certificate #1823

Open
vipetrov-bg opened this issue Feb 15, 2024 · 2 comments

Comments

@vipetrov-bg
Copy link

Expected behavior

Perform request graphClient.applications().byApplicationId("") .patch(app) if try to add a new certificate and there are old configured certificates.

If there are not old configured certificates the call is successful!

The old issue with 6.1 version was java.time.format.DateTimeParseException: Text '2024-02-14T07:37:32' could not be parsed at index 19: #1815

Actual behavior

2024-02-15 10:09:48 INFO c.a.i.ClientCertificateCredential - Azure Identity => getToken() result for scopes [https://graph.microsoft.com/.default]: SUCCESS
2024-02-15 10:09:52 INFO c.m.a.m.AcquireTokenSilentSupplier - Returning token from cache
2024-02-15 10:09:52 INFO c.a.i.ClientCertificateCredential - Azure Identity => getToken() result for scopes [https://graph.microsoft.com/.default]: SUCCESS
com.microsoft.graph.models.odataerrors.ODataError: The value for the property "usage" in one of your credentials is invalid. Acceptable values are Sign, Verify.
at com.microsoft.graph.models.odataerrors.ODataError.createFromDiscriminatorValue(ODataError.java:36)
at com.microsoft.kiota.serialization.JsonParseNode.getObjectValue(JsonParseNode.java:210)
at com.microsoft.kiota.http.OkHttpRequestAdapter.lambda$throwIfFailedResponse$0(OkHttpRequestAdapter.java:672)
at com.microsoft.kiota.ApiExceptionBuilder.(ApiExceptionBuilder.java:26)
at com.microsoft.kiota.http.OkHttpRequestAdapter.throwIfFailedResponse(OkHttpRequestAdapter.java:671)
at com.microsoft.kiota.http.OkHttpRequestAdapter.send(OkHttpRequestAdapter.java:279)
at com.microsoft.graph.applications.item.ApplicationItemRequestBuilder.patch(ApplicationItemRequestBuilder.java:297)
at com.microsoft.graph.applications.item.ApplicationItemRequestBuilder.patch(ApplicationItemRequestBuilder.java:281)

Steps to reproduce the behavior

    TokenCredential tokenCredential = new ClientCertificateCredentialBuilder().tenantId(tenantId)
    .clientId(clientId).pfxCertificate(pfxCertificatePath).clientCertificatePassword(pfxPassword)
    .build();

    String[] scopes = new String[] { "https://graph.microsoft.com/.default" };

    GraphServiceClient graphClient = new GraphServiceClient(tokenCredential, scopes);

    Application app = graphClient.applications().byApplicationId("<my app id>").get();

    List<KeyCredential> keyCredentialList = app.getKeyCredentials(); // There are old KeyCredentials

    X509Certificate certificate = ... //new certificate

    KeyCredential newKey = new KeyCredential();
    newKey.setType("AsymmetricX509Cert");
    newKey.setUsage("Verify");
    newKey.setKey(certificate.getEncoded());

    keyCredentialList.add(newKey);

    app.setKeyCredentials(keyCredentialList);

    Application updatedApp = graphClient.applications().byApplicationId("<my app id>")
            .patch(app);

Workaround by skipping odata

    TokenCredential tokenCredential = new ClientCertificateCredentialBuilder().tenantId(tenantId)
    .clientId(clientId).pfxCertificate(pfxCertificatePath).clientCertificatePassword(pfxPassword)
    .build();

    String[] scopes = new String[] { "https://graph.microsoft.com/.default" };

    GraphServiceClient graphClient = new GraphServiceClient(tokenCredential, scopes);

    Application app = graphClient.applications().byApplicationId("<my app id>").get();

    List<KeyCredential> keyCredentialListOld = app.getKeyCredentials(); // There are old KeyCredentials

    // create a new Key Credential List and add old Key Credentials as using getters and setters
    List<KeyCredential> keyCredentialList = new ArrayList<>();
    for (KeyCredential key : keyCredentialListOld) {
        KeyCredential oldKey = new KeyCredential();
        oldKey.setDisplayName(key.getDisplayName());
        oldKey.setCustomKeyIdentifier(key.getCustomKeyIdentifier());
        oldKey.setKeyId(key.getKeyId());
        oldKey.setKey(key.getKey());
        oldKey.setStartDateTime(key.getStartDateTime());
        oldKey.setEndDateTime(key.getEndDateTime());
        oldKey.setUsage(key.getUsage());
        oldKey.setType(key.getType());
        // Skip Odata Type
        keyCredentialList.add(oldKey);
    }

    X509Certificate certificate = ... //new certificate

    KeyCredential newKey = new KeyCredential();
    newKey.setType("AsymmetricX509Cert");
    newKey.setUsage("Verify");
    newKey.setKey(certificate.getEncoded());

    keyCredentialList.add(newKey);

    app.setKeyCredentials(keyCredentialList);

    Application updatedApp = graphClient.applications().byApplicationId("<my app id>")
            .patch(app);
@ramsessanchez
Copy link
Contributor

Hi @vipetrov-bg ,
I believe that despite the old keys being present they too must be reconfigured. At least that is what I was able to gather from reading the docs. Take a look at the second example, I believe this may be a better reflection of your scenario.

@vipetrov-bg
Copy link
Author

Hi @ramsessanchez

I saw second example. First it has bug because the thumbprint 52ED9B5038A47B9E2E2190715CC238359D4F8F73 is in hex string format and this byte[] customKeyIdentifier = Base64.getDecoder().decode("52ED9B5038A47B9E2E2190715CC238359D4F8F73"); will not work, it expects base64 format.

But my workaround is OK because it uses previous thumbprint ie oldKey.setCustomKeyIdentifier(key.getCustomKeyIdentifier());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants