microsoft-authentication-library-for-dotnet
microsoft-authentication-library-for-dotnet copied to clipboard
[Feature Request] MSAL support for other IdP's such as Okta
Hi, is MSAL only compatible with MS Authorization servers or we could use it with other authorization server as well? I'm trying to use it with Okta and the first error I'm getting is about the ClientID which should be a Guid, because of this code:
//Adfs does not require client id to be in the form of a Guid
if (Config.AuthorityInfo?.AuthorityType != AuthorityType.Adfs && !Guid.TryParse(Config.ClientId, out _))
{
throw new MsalClientException(MsalError.ClientIdMustBeAGuid, MsalErrorMessage.ClientIdMustBeAGuid);
}
OAuth / OpenId does not seem to have any particular restriction on ClientID to be a GUID.
MSAL only works with MS Identity Providers (AAD, B2C and ADFS) at this time.
Thanks for the answer Bogdan. Yes that's what I guessed. Would be great to support other IDPs that respect the OpenId/OAuth standard.
@jmprieur to check with PM team if this would be a goal. Note that big companies rely on multiple clouds (Google cloud, AWS, ...)
Would also be useful for 'smaller things' like Adobe Sign.
Would love it too. The comment below for a WithAuthority constructor gave me some hope:
This constructor is mainly used for scenarios where the authority is not a standard Azure AD authority, nor an ADFS authority, nor an Azure AD B2C authority.
Oh crikey.
MSAL seems to be the one dotnet library that manages token refreshing, and is properly integrated with AspNetCore.
But, applications frequently need to integrate with other applications. Its the reason we use open standards like OpenID and OAuth.
I need to deal with federated auth that only includes AzureAD as part of the stack. Finding out I can't use Microsoft.Identity.* to get and refresh my Keycloak and Okta tokens just wastes the time I've spend on the AzureAD part of the integration because now there is no general solution that covers all my target IdPs.
I guess I'm back to trying to do everything the hard way with IdentityModel
I support this request.
I support this request.
For the public client / desktop app, @mjcheetham built a very nice general-purpose OAuth2 layer in Git Credential Manager - https://github.com/GitCredentialManager/git-credential-manager/tree/main/src/shared/Core/Authentication/OAuth
Found this, so it may be possible for other identity providers as well, would just need to test and document the settings.
https://www.frodehus.dev/use-keycloak-and-msal-with-react-spa/
Would a PR be accepted to bring support of OAuth2 authorization server metadata and/or OpenIdConnect discovery endpoint to configure MSAL.NET in non AzureAD context ?
I see there is generic authority support in the confidential client app but not the public client app... would the generic (non-azure) authority be considered for the public client app interactive request? Are there any plans for that?
Is there a sample for the new WithGenericAuthority method? I'm trying to use MSAL to get a token from salesforce, but there doesn't seem to be any documentation.
No, we don't have a sample yet. Happy to answer any questions on this @Joffreyvl .
You configure the authority as below. Note that PublicClientApplication is not yet supported.
var msal = ConfidentialClientApplicationBuilder
.Create(ClientId)
.WithExperimentalFeatures(true)
.WithRedirectUri(RedirectUri)
.WithClientSecret(ClientSecret)
.WithGenericAuthority($"https://demo.duendesoftware.com/")
.Build();
Note that MSAL will append .well-knwon/openid-configuration
to your authority string to figure out the token endpoint address, e.g.
https://demo.duendesoftware.com/.well-known/openid-configuration
I see there is generic authority support in the confidential client app but not the public client app... would the generic (non-azure) authority be considered for the public client app interactive request? Are there any plans for that?
Yeah, we'll have to add support for this for public client as well, but I don't have an ETA yet.
@bgavrilMS thanks for the response, this is the code I have now.
var confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithExperimentalFeatures(true)
.WithClientSecret(clientSecret)
.WithGenericAuthority(baseUrl)
.Build();
var authResult = await confidentialClientApplication
.AcquireTokenForClient(new[] { "openid", "api" })
.ExecuteAsync(cancellationToken);
But when acquiring the token I get this exception: Microsoft.Identity.Client.MsalServiceException: 'scope parameter not supported'
@Joffreyvl - AcquireTokenForClient
uses the "client_credentials" flow. This is meant for app to app communication. Does SalesForce support that ? "openid" is a scope that is typical of user authentication, it controls issuance of an ID Token.
What kind of app are you trying to build? A console app, a web site, a web api?
@bgavrilMS I found the solution, the Salesforce api doesn't allow me to send scopes. MSAL requires you to provide at least one scope. To solve this, I added whitespace as scope.
var authResult = await confidentialClientApplication
.AcquireTokenForClient(new[] { " " })
.ExecuteAsync();
I don't know if this is a bad implementation of de OAuth standard on Salesforces side or MSAL?
Well MSAL was originally designed to be the SDK for Azure AD, and with Azure AD client_credentials always takes a scope, so that's why the argument is mandatory. Many Identity Providers don't allow scopes and just return a token with permissions to whatever your service principal is allowed to access. I created https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4482 to track this, but the workaround you have seems pretty easy to use.
Can you try to get the same token again (i.e. make 2 requests one after the other) and check authResult.AuthenticationResultMetadata.TokenSource
- I expect it to be "Cache". Does the token expiration look ok?
Well MSAL was originally designed to be the SDK for Azure AD, and with Azure AD client_credentials always takes a scope, so that's why the argument is mandatory. Many Identity Providers don't allow scopes and just return a token with permissions to whatever your service principal is allowed to access. I created #4482 to track this, but the workaround you have seems pretty easy to use.
Can you try to get the same token again (i.e. make 2 requests one after the other) and check
authResult.AuthenticationResultMetadata.TokenSource
- I expect it to be "Cache". Does the token expiration look ok?
Token is the same when I do multiple requests but authResult.AuthenticationResultMetadata.TokenSource is IdentityProvider in all requests, CacheLevel is set to None
Is there an option to completely disable the well-known discovery check using WithGenericAuthority?
I have a scenario where this document doesn’t actually exist and the config data needs to be manually populated.
@trycatchdonothing - we were thinking of adding some helper to allow apps to provide their own metadata. Mostly because ASP.NET Core will do the OIDC discovery on its own and then MSAL takes over, so it results in 2 calls to OIDC.
Please create a new issue.
I am closing this as it will be avaialble on next MSAL 4.60.0 (eta - a few days)
API is experiemtanl for public client, GA for confidential.
Fixed in MSAL.Net 4.60.0 release