Browse Source

Update the LinkedIn provider to use "Sign In with LinkedIn V2"

pull/1778/head
Kévin Chalet 3 years ago
parent
commit
620c3954d0
  1. 54
      gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs
  2. 12
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs
  3. 13
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  4. 22
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml
  5. 10
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd

54
gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs

@ -46,6 +46,7 @@ namespace OpenIddict.Client.WebIntegration.Generators
static string GenerateBuilderMethods(XDocument document) static string GenerateBuilderMethods(XDocument document)
{ {
var template = Template.Parse(@"#nullable enable var template = Template.Parse(@"#nullable enable
#pragma warning disable CS0618
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
@ -284,6 +285,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Add{{ setting.property_name }}(params {{ setting.clr_type }}[] {{ setting.parameter_name }}) public {{ provider.name }} Add{{ setting.property_name }}(params {{ setting.clr_type }}[] {{ setting.parameter_name }})
{ {
if ({{ setting.parameter_name }} is null) if ({{ setting.parameter_name }} is null)
@ -299,6 +303,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(ECDsaSecurityKey {{ setting.parameter_name }}) public {{ provider.name }} Set{{ setting.property_name }}(ECDsaSecurityKey {{ setting.parameter_name }})
{ {
if ({{ setting.parameter_name }} is null) if ({{ setting.parameter_name }} is null)
@ -322,6 +329,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key. /// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key.
/// </param> /// </param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(string key) public {{ provider.name }} Set{{ setting.property_name }}(string key)
=> Set{{ setting.property_name }}(key.AsMemory()); => Set{{ setting.property_name }}(key.AsMemory());
@ -332,6 +342,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key. /// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key.
/// </param> /// </param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(ReadOnlyMemory<char> key) public {{ provider.name }} Set{{ setting.property_name }}(ReadOnlyMemory<char> key)
=> Set{{ setting.property_name }}(key.Span); => Set{{ setting.property_name }}(key.Span);
@ -342,6 +355,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key. /// The PEM-encoded Elliptic Curve Digital Signature Algorithm (ECDSA) signing key.
/// </param> /// </param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(ReadOnlySpan<char> key) public {{ provider.name }} Set{{ setting.property_name }}(ReadOnlySpan<char> key)
{ {
if (key.IsEmpty) if (key.IsEmpty)
@ -372,6 +388,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(Uri {{ setting.parameter_name }}) public {{ provider.name }} Set{{ setting.property_name }}(Uri {{ setting.parameter_name }})
{ {
if ({{ setting.parameter_name }} is null) if ({{ setting.parameter_name }} is null)
@ -392,6 +411,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(string {{ setting.parameter_name }}) public {{ provider.name }} Set{{ setting.property_name }}(string {{ setting.parameter_name }})
{ {
if (string.IsNullOrEmpty({{ setting.parameter_name }})) if (string.IsNullOrEmpty({{ setting.parameter_name }}))
@ -407,6 +429,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(X509Certificate2 {{ setting.parameter_name }}) public {{ provider.name }} Set{{ setting.property_name }}(X509Certificate2 {{ setting.parameter_name }})
{ {
if ({{ setting.parameter_name }} is null) if ({{ setting.parameter_name }} is null)
@ -429,6 +454,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// <param name=""resource"">The name of the embedded resource.</param> /// <param name=""resource"">The name of the embedded resource.</param>
/// <param name=""password"">The password used to open the certificate.</param> /// <param name=""password"">The password used to open the certificate.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(Assembly assembly, string resource, string? password) public {{ provider.name }} Set{{ setting.property_name }}(Assembly assembly, string resource, string? password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
@ -447,6 +475,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// <param name=""password"">The password used to open the certificate.</param> /// <param name=""password"">The password used to open the certificate.</param>
/// <param name=""flags"">An enumeration of flags indicating how and where to store the private key of the certificate.</param> /// <param name=""flags"">An enumeration of flags indicating how and where to store the private key of the certificate.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}( public {{ provider.name }} Set{{ setting.property_name }}(
Assembly assembly, string resource, Assembly assembly, string resource,
string? password, X509KeyStorageFlags flags) string? password, X509KeyStorageFlags flags)
@ -473,6 +504,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// <param name=""stream"">The stream containing the certificate.</param> /// <param name=""stream"">The stream containing the certificate.</param>
/// <param name=""password"">The password used to open the certificate.</param> /// <param name=""password"">The password used to open the certificate.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(Stream stream, string? password) public {{ provider.name }} Set{{ setting.property_name }}(Stream stream, string? password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
@ -493,6 +527,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// to store the private key of the certificate. /// to store the private key of the certificate.
/// </param> /// </param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(Stream stream, string? password, X509KeyStorageFlags flags) public {{ provider.name }} Set{{ setting.property_name }}(Stream stream, string? password, X509KeyStorageFlags flags)
{ {
if (stream is null) if (stream is null)
@ -511,6 +548,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""thumbprint"">The thumbprint of the certificate used to identify it in the X.509 store.</param> /// <param name=""thumbprint"">The thumbprint of the certificate used to identify it in the X.509 store.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(string thumbprint) public {{ provider.name }} Set{{ setting.property_name }}(string thumbprint)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
@ -541,6 +581,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// <param name=""name"">The name of the X.509 store.</param> /// <param name=""name"">The name of the X.509 store.</param>
/// <param name=""location"">The location of the X.509 store.</param> /// <param name=""location"">The location of the X.509 store.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}(string thumbprint, StoreName name, StoreLocation location) public {{ provider.name }} Set{{ setting.property_name }}(string thumbprint, StoreName name, StoreLocation location)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
@ -562,6 +605,9 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// </summary> /// </summary>
/// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param> /// <param name=""{{ setting.parameter_name }}"">{{ setting.description | string.capitalize }}.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns> /// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
public {{ provider.name }} Set{{ setting.property_name }}({{ setting.clr_type }} {{ setting.parameter_name }}) public {{ provider.name }} Set{{ setting.property_name }}({{ setting.clr_type }} {{ setting.parameter_name }})
{ {
if ({{ setting.parameter_name }} is null) if ({{ setting.parameter_name }} is null)
@ -611,6 +657,8 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
ParameterName = (string) setting.Attribute("ParameterName"), ParameterName = (string) setting.Attribute("ParameterName"),
Collection = (bool?) setting.Attribute("Collection") ?? false, Collection = (bool?) setting.Attribute("Collection") ?? false,
Obsolete = (bool?) setting.Attribute("Obsolete") ?? false,
Description = (string) setting.Attribute("Description") is string description ? Description = (string) setting.Attribute("Description") is string description ?
char.ToLower(description[0], CultureInfo.GetCultureInfo("en-US")) + description[1..] : null, char.ToLower(description[0], CultureInfo.GetCultureInfo("en-US")) + description[1..] : null,
ClrType = (string) setting.Attribute("Type") switch ClrType = (string) setting.Attribute("Type") switch
@ -687,6 +735,7 @@ public static partial class OpenIddictClientWebIntegrationConstants
static string GenerateConfigurationClasses(XDocument document) static string GenerateConfigurationClasses(XDocument document)
{ {
var template = Template.Parse(@"#nullable enable var template = Template.Parse(@"#nullable enable
#pragma warning disable CS0618
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -1155,6 +1204,9 @@ public sealed partial class OpenIddictClientWebIntegrationOptions
/// <summary> /// <summary>
/// Gets or sets {{ setting.description }}. /// Gets or sets {{ setting.description }}.
/// </summary> /// </summary>
{{~ if setting.obsolete ~}}
[Obsolete(""This option is no longer supported and will be removed in a future version."")]
{{~ end ~}}
{{~ if setting.collection ~}} {{~ if setting.collection ~}}
public HashSet<{{ setting.clr_type }}> {{ setting.property_name }} { get; } = new(); public HashSet<{{ setting.clr_type }}> {{ setting.property_name }} { get; } = new();
{{~ else ~}} {{~ else ~}}
@ -1179,6 +1231,8 @@ public sealed partial class OpenIddictClientWebIntegrationOptions
PropertyName = (string) setting.Attribute("PropertyName"), PropertyName = (string) setting.Attribute("PropertyName"),
Collection = (bool?) setting.Attribute("Collection") ?? false, Collection = (bool?) setting.Attribute("Collection") ?? false,
Obsolete = (bool?) setting.Attribute("Obsolete") ?? false,
Description = (string) setting.Attribute("Description") is string description ? Description = (string) setting.Attribute("Description") is string description ?
char.ToLower(description[0], CultureInfo.GetCultureInfo("en-US")) + description[1..] : null, char.ToLower(description[0], CultureInfo.GetCultureInfo("en-US")) + description[1..] : null,
ClrType = (string) setting.Attribute("Type") switch ClrType = (string) setting.Attribute("Type") switch

12
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs

@ -101,7 +101,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
// authorization code or implicit flows). To work around that, the list of supported grant // authorization code or implicit flows). To work around that, the list of supported grant
// types is amended to include the known supported types for the providers that require it. // types is amended to include the known supported types for the providers that require it.
if (context.Registration.ProviderName is Providers.Apple or Providers.QuickBooksOnline) if (context.Registration.ProviderName is Providers.Apple or Providers.LinkedIn or Providers.QuickBooksOnline)
{ {
context.Configuration.GrantTypesSupported.Add(GrantTypes.AuthorizationCode); context.Configuration.GrantTypesSupported.Add(GrantTypes.AuthorizationCode);
context.Configuration.GrantTypesSupported.Add(GrantTypes.RefreshToken); context.Configuration.GrantTypesSupported.Add(GrantTypes.RefreshToken);
@ -278,6 +278,16 @@ public static partial class OpenIddictClientWebIntegrationHandlers
ClientAuthenticationMethods.PrivateKeyJwt); 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; return default;
} }
} }

13
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs

@ -60,6 +60,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/// </summary> /// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; } public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessAuthenticationContext>() = OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessAuthenticationContext>()
.AddFilter<RequireRedirectionRequest>()
.UseSingletonHandler<HandleNonStandardFrontchannelErrorResponse>() .UseSingletonHandler<HandleNonStandardFrontchannelErrorResponse>()
.SetOrder(HandleFrontchannelErrorResponse.Descriptor.Order - 500) .SetOrder(HandleFrontchannelErrorResponse.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn) .SetType(OpenIddictClientHandlerType.BuiltIn)
@ -394,7 +395,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.DisableBackchannelIdentityTokenNonceValidation = context.Registration.ProviderName switch context.DisableBackchannelIdentityTokenNonceValidation = context.Registration.ProviderName switch
{ {
// These providers don't include the nonce in their identity tokens: // 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 _ => context.DisableBackchannelIdentityTokenNonceValidation
}; };
@ -582,16 +583,6 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.UserinfoRequest["fields"] = string.Join(",", options.Fields); 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 // Patreon limits the number of fields returned by the userinfo endpoint
// but allows returning additional information using special parameters that // but allows returning additional information using special parameters that
// determine what fields will be returned as part of the userinfo response. // determine what fields will be returned as part of the userinfo response.

22
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

@ -414,8 +414,7 @@
</Configuration> </Configuration>
<!-- <!--
Note: HubSpot requires sending the "profile" scope to Note: HubSpot requires sending the "oauth" scope to be able to use the dynamic access token info endpoint.
be able to use the dynamic access token info endpoint.
--> -->
<Scope Name="oauth" Default="true" Required="true" /> <Scope Name="oauth" Default="true" Required="true" />
@ -450,25 +449,16 @@
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
--> -->
<Provider Name="LinkedIn" Documentation="https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin"> <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/"> <Environment Issuer="https://www.linkedin.com/" ConfigurationEndpoint="https://www.linkedin.com/oauth/.well-known/openid-configuration">
<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>
<!-- <!--
Note: LinkedIn requires sending at least one scope element. If no scope is set, an error is Note: LinkedIn requires sending the "profile" scope to be able to use the userinfo endpoint.
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.
--> -->
<Scope Name="r_liteprofile" Default="true" Required="true" /> <Scope Name="profile" Default="true" Required="true" />
</Environment> </Environment>
<Setting PropertyName="Fields" ParameterName="fields" Collection="true" Type="String" <Setting PropertyName="Fields" ParameterName="fields" Collection="true" Obsolete="true" Type="String"
Description="The fields that should be retrieved from the userinfo endpoint (by default, all known basic fields are requested)"> 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="firstName" Default="true" Required="false" />
<Item Value="id" Default="true" Required="false" /> <Item Value="id" Default="true" Required="false" />

10
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd

@ -398,6 +398,16 @@
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="Obsolete" use="optional">
<xs:annotation>
<xs:documentation>A boolean indicating whether the setting is obsolete.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:boolean" />
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Type" use="required"> <xs:attribute name="Type" use="required">
<xs:annotation> <xs:annotation>
<xs:documentation>The setting type.</xs:documentation> <xs:documentation>The setting type.</xs:documentation>

Loading…
Cancel
Save