Skip to content

Commit

Permalink
Update the LinkedIn provider to use "Sign In with LinkedIn V2"
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinchalet committed May 20, 2023
1 parent 0cf3b87 commit ee62ff5
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
ClientAuthenticationMethods.PrivateKeyJwt);
}

// LinkedIn doesn't support sending the client credentials using basic authentication but
// doesn't return a "token_endpoint_auth_methods_supported" node containing alternative
// authentication methods, making basic authentication the default authentication method.
// To work around this compliance issue, "client_secret_post" is manually added here.
else if (context.Registration.ProviderName is Providers.LinkedIn)
{
context.Configuration.TokenEndpointAuthMethodsSupported.Add(
ClientAuthenticationMethods.ClientSecretPost);
}

return default;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public sealed class HandleNonStandardFrontchannelErrorResponse : IOpenIddictClie
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessAuthenticationContext>()
.AddFilter<RequireRedirectionRequest>()
.UseSingletonHandler<HandleNonStandardFrontchannelErrorResponse>()
.SetOrder(HandleFrontchannelErrorResponse.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)
Expand Down Expand Up @@ -394,7 +395,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context)
context.DisableBackchannelIdentityTokenNonceValidation = context.Registration.ProviderName switch
{
// These providers don't include the nonce in their identity tokens:
Providers.Asana or Providers.Dropbox or Providers.QuickBooksOnline => true,
Providers.Asana or Providers.Dropbox or Providers.LinkedIn or Providers.QuickBooksOnline => true,

_ => context.DisableBackchannelIdentityTokenNonceValidation
};
Expand Down Expand Up @@ -582,16 +583,6 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context)
context.UserinfoRequest["fields"] = string.Join(",", options.Fields);
}

// By default, LinkedIn returns all the basic fields except the profile image.
// To retrieve the profile image, a projection parameter must be sent with
// all the parameters that should be returned from the userinfo endpoint.
else if (context.Registration.ProviderName is Providers.LinkedIn)
{
var options = context.Registration.GetLinkedInOptions();

context.UserinfoRequest["projection"] = string.Concat("(", string.Join(",", options.Fields), ")");
}

// Patreon limits the number of fields returned by the userinfo endpoint
// but allows returning additional information using special parameters that
// determine what fields will be returned as part of the userinfo response.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@
</Configuration>

<!--
Note: HubSpot requires sending the "profile" scope to
be able to use the dynamic access token info endpoint.
Note: HubSpot requires sending the "oauth" scope to be able to use the dynamic access token info endpoint.
-->

<Scope Name="oauth" Default="true" Required="true" />
Expand Down Expand Up @@ -450,33 +449,14 @@
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->

<Provider Name="LinkedIn" Documentation="https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin">
<Environment Issuer="https://www.linkedin.com/">
<Configuration AuthorizationEndpoint="https://www.linkedin.com/oauth/v2/authorization"
TokenEndpoint="https://www.linkedin.com/oauth/v2/accessToken"
UserinfoEndpoint="https://api.linkedin.com/v2/me">
<GrantType Value="authorization_code" />
<GrantType Value="refresh_token" />
</Configuration>

<Provider Name="LinkedIn" Documentation="https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2">
<Environment Issuer="https://www.linkedin.com/" ConfigurationEndpoint="https://www.linkedin.com/oauth/.well-known/openid-configuration">
<!--
Note: LinkedIn requires sending at least one scope element. If no scope is set, an error is
returned to the caller. To prevent that, the "r_liteprofile" scope (that is required by the
userinfo endpoint) is always added even if another scope was explicitly registered by the user.
Note: LinkedIn requires sending the "profile" scope to be able to use the userinfo endpoint.
-->

<Scope Name="r_liteprofile" Default="true" Required="true" />
<Scope Name="profile" Default="true" Required="true" />
</Environment>

<Setting PropertyName="Fields" ParameterName="fields" Collection="true" Type="String"
Description="The fields that should be retrieved from the userinfo endpoint (by default, all known basic fields are requested)">
<Item Value="firstName" Default="true" Required="false" />
<Item Value="id" Default="true" Required="false" />
<Item Value="lastName" Default="true" Required="false" />
<Item Value="localizedFirstName" Default="true" Required="false" />
<Item Value="localizedLastName" Default="true" Required="false" />
<Item Value="profilePicture(displayImage~:playableStreams)" Default="true" Required="false" />
</Setting>
</Provider>

<!--
Expand Down

0 comments on commit ee62ff5

Please sign in to comment.