-
Notifications
You must be signed in to change notification settings - Fork 134
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
Authenticate with application id using Certificated-based Authentication #2075
Comments
I tried the following but all failed.
please help. |
Is anyone working on this issue? I have to resolve this issue as soon as possible. |
@0B7002 I'll try to reproduce this and get back to you later today. Apologies for the delay |
When can I get a reply? |
Is anyone working on this issue? |
Sorry for the delay @0B7002. From my understanding of certificate-based authentication & these docs what you should be uploading to your app registration is the X509 certificate generated. From Azure Identity's logic it seems that we expect a certificate file containing a private key. The certs generated by OpenSSL only have the public key in the encoded payload. Still investigating this. |
Thank you for your answer. As mentioned earlier, I generated and uploaded a public key with the x509 option. And I read docs but could not find how to generate pem file. What kind of files should I upload to my app and how to generate it? what value should I specify to |
From my understanding, this error has occured causing private key, not public key. And as mentioned earlier, I created public/private key using openssl, Here is the commands.
So I tried to get public key information from private key by a following command, and suceed.
Why |
Using the same public/private key, I successed to get access token by the following code. // private key
byte[] encoded = Base64.getDecoder().decode("[private key]");
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(encoded));
// public key
X509Certificate publicKey = (X509Certificate) CertificateFactory.getInstance("X.509")
.generateCertificate(Files.newInputStream(Paths.get("[public key file path]")));
// parameter
String authority = "https://login.microsoftonline.com/[tenantid]/";
Set<String> scope = Set.of("https://graph.microsoft.com/.default");
// client
IClientCredential credential = ClientCredentialFactory.createFromCertificate(privateKey, publicKey);
ConfidentialClientApplication cca = ConfidentialClientApplication.builder("[clientid]", credential)
.authority(authority)
.build();
ClientCredentialParameters parameters = ClientCredentialParameters.builder(scope).build();
// get token
CompletableFuture<IAuthenticationResult> result = cca.acquireToken(parameters);
System.out.println(result.get().accessToken()); Because of this, I think that the public/private key is correct. How to do this in using GraphServiceClient? |
Using a private key and thumbprint, I successed to authorize by the following code. import java.security.KeyFactory;
import java.security.interfaces.RSAKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.OffsetDateTime;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.codec.binary.Hex;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.azure.core.credential.TokenCredential;
import com.azure.identity.ClientAssertionCredentialBuilder;
import com.microsoft.graph.serviceclient.GraphServiceClient;
public class MyService {
public GraphServiceClient getGraphClient() throws Exception {
// private key
byte[] encoded = Base64.getDecoder().decode("[private key base64 text]");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
RSAKey privateKey = (RSAKey) KeyFactory.getInstance("RSA").generatePrivate(keySpec);
// generate JWT
byte[] bytes = Hex.decodeHex("thumbprint".toCharArray());
String x5t = Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
Map<String, Object> header = new HashMap<>();
header.put("x5t", x5t);
String assertion = JWT.create()
.withHeader(header)
.withAudience("https://login.microsoftonline.com/" + "[tenantId]" + "/oauth2/v2.0/token")
.withExpiresAt(OffsetDateTime.now().plusMinutes(5).toInstant())
.withIssuer("[clientId]")
.withJWTId(UUID.randomUUID().toString())
.withNotBefore(OffsetDateTime.now().toInstant())
.withSubject("[clientId]")
.withIssuedAt(OffsetDateTime.now().toInstant())
.sign(Algorithm.RSA256(privateKey));
// generate GraphServiceClient
TokenCredential credential = new ClientAssertionCredentialBuilder().tenantId("[tenantId]")
.clientId("[clientId]")
.clientAssertion(() -> assertion)
.build();
return new GraphServiceClient(credential);
}
} Is this a best practice? |
I registered the app on the Microsoft Entra admin center by referring to this page:
https://learn.microsoft.com/en-us/graph/auth-v2-service?tabs=http
Then I created public/private key using openssl. Here is the commands.
Uploaded the public key (ms365-private.key) on the Microsoft Entra admin center, and I created this code.
but if i execute some methods on this graphClient , this following error occurs
Q. Should I also specify public key? If so, how to specify public key by using ClientCertificateCredentialBuilder?
The text was updated successfully, but these errors were encountered: