microsoft-authentication-library-for-dotnet icon indicating copy to clipboard operation
microsoft-authentication-library-for-dotnet copied to clipboard

[Feature Request] MSAL support for other IdP's such as Okta

Open adefalque opened this issue 5 years ago • 20 comments

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.

adefalque avatar Dec 06 '19 10:12 adefalque

MSAL only works with MS Identity Providers (AAD, B2C and ADFS) at this time.

bgavrilMS avatar Dec 06 '19 16:12 bgavrilMS

Thanks for the answer Bogdan. Yes that's what I guessed. Would be great to support other IDPs that respect the OpenId/OAuth standard.

adefalque avatar Dec 06 '19 20:12 adefalque

@jmprieur to check with PM team if this would be a goal. Note that big companies rely on multiple clouds (Google cloud, AWS, ...)

jmprieur avatar Dec 19 '19 18:12 jmprieur

Would also be useful for 'smaller things' like Adobe Sign.

fowl2 avatar Jan 02 '20 04:01 fowl2

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.

mliesmons avatar Apr 18 '20 14:04 mliesmons

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

chrisbecke avatar Aug 21 '21 10:08 chrisbecke

I support this request.

ghost avatar Sep 17 '21 18:09 ghost

I support this request.

nthurner avatar Jan 17 '22 11:01 nthurner

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

bgavrilMS avatar Jan 17 '22 12:01 bgavrilMS

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/

bigjonroberts avatar Dec 14 '22 16:12 bigjonroberts

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 ?

g7ed6e avatar Jan 23 '23 17:01 g7ed6e

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?

randbrown avatar Aug 14 '23 17:08 randbrown

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.

Joffreyvl avatar Dec 22 '23 11:12 Joffreyvl

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

bgavrilMS avatar Dec 22 '23 11:12 bgavrilMS

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 avatar Dec 22 '23 11:12 bgavrilMS

@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 avatar Dec 22 '23 11:12 Joffreyvl

@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 avatar Dec 22 '23 11:12 bgavrilMS

@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?

Joffreyvl avatar Dec 22 '23 12:12 Joffreyvl

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?

bgavrilMS avatar Dec 22 '23 13:12 bgavrilMS

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

Joffreyvl avatar Dec 22 '23 14:12 Joffreyvl

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 avatar Mar 06 '24 22:03 trycatchdonothing

@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.

bgavrilMS avatar Mar 07 '24 12:03 bgavrilMS

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.

bgavrilMS avatar Mar 07 '24 12:03 bgavrilMS

Fixed in MSAL.Net 4.60.0 release

neha-bhargava avatar Mar 27 '24 22:03 neha-bhargava