-
Notifications
You must be signed in to change notification settings - Fork 532
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b9c840e
commit 14618f6
Showing
11 changed files
with
411 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/AspNet.Security.OAuth.Salesforce/AspNet.Security.OAuth.Salesforce.xproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> | ||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | ||
</PropertyGroup> | ||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> | ||
<PropertyGroup Label="Globals"> | ||
<ProjectGuid>5881bb63-89bd-4397-a61c-69b1844f7615</ProjectGuid> | ||
<RootNamespace>AspNet.Security.OAuth.Salesforce</RootNamespace> | ||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> | ||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
</PropertyGroup> | ||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> | ||
</Project> |
64 changes: 64 additions & 0 deletions
64
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationDefaults.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Authentication.OAuth; | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
/// <summary> | ||
/// Default values used by the Salesforce authentication middleware. | ||
/// </summary> | ||
public static class SalesforceAuthenticationDefaults { | ||
/// <summary> | ||
/// Default value for <see cref="AuthenticationOptions.AuthenticationScheme"/>. | ||
/// </summary> | ||
public const string AuthenticationScheme = "Salesforce"; | ||
|
||
/// <summary> | ||
/// Default value for <see cref="RemoteAuthenticationOptions.DisplayName"/>. | ||
/// </summary> | ||
public const string DisplayName = "Salesforce"; | ||
|
||
/// <summary> | ||
/// Default value for <see cref="AuthenticationOptions.ClaimsIssuer"/>. | ||
/// </summary> | ||
public const string Issuer = "Salesforce"; | ||
|
||
/// <summary> | ||
/// Default value for <see cref="RemoteAuthenticationOptions.CallbackPath"/>. | ||
/// </summary> | ||
public const string CallbackPath = "/signin-salesforce"; | ||
|
||
/// <summary> | ||
/// Default value for the Salesforce environment (production or test) | ||
/// </summary> | ||
public const SalesforceAuthenticationEnvironment Environment = SalesforceAuthenticationEnvironment.Production; | ||
|
||
public static class Production { | ||
/// <summary> | ||
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>. | ||
/// </summary> | ||
public const string AuthorizationEndpoint = "https://login.salesforce.com/services/oauth2/authorize"; | ||
|
||
/// <summary> | ||
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>. | ||
/// </summary> | ||
public const string TokenEndpoint = "https://login.salesforce.com/services/oauth2/token"; | ||
} | ||
|
||
public static class Test { | ||
/// <summary> | ||
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>. | ||
/// </summary> | ||
public const string AuthorizationEndpoint = "https://test.salesforce.com/services/oauth2/authorize"; | ||
|
||
/// <summary> | ||
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>. | ||
/// </summary> | ||
public const string TokenEndpoint = "https://test.salesforce.com/services/oauth2/token"; | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationEnvironment.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
/// <summary> | ||
/// Defines a list of environments used to determine the appropriate | ||
/// OAuth2 endpoints when communicating with Salesforce. | ||
/// </summary> | ||
public enum SalesforceAuthenticationEnvironment { | ||
/// <summary> | ||
/// Use login.salesforce.com in the OAuth2 endpoints. | ||
/// </summary> | ||
Production = 0, | ||
|
||
/// <summary> | ||
/// Uses test.salesforce.com in the OAuth2 endpoints. | ||
/// </summary> | ||
Test = 1 | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using System; | ||
using AspNet.Security.OAuth.Salesforce; | ||
using JetBrains.Annotations; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Microsoft.AspNetCore.Builder { | ||
/// <summary> | ||
/// Extension methods to add Salesforce authentication capabilities to an HTTP application pipeline. | ||
/// </summary> | ||
public static class SalesforceAuthenticationExtensions { | ||
/// <summary> | ||
/// Adds the <see cref="SalesforceAuthenticationMiddleware"/> middleware to the specified | ||
/// <see cref="IApplicationBuilder"/>, which enables Salesforce authentication capabilities. | ||
/// </summary> | ||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param> | ||
/// <param name="options">A <see cref="SalesforceAuthenticationOptions"/> that specifies options for the middleware.</param> | ||
/// <returns>A reference to this instance after the operation has completed.</returns> | ||
public static IApplicationBuilder UseSalesforceAuthentication( | ||
[NotNull] this IApplicationBuilder app, | ||
[NotNull] SalesforceAuthenticationOptions options) { | ||
if (app == null) { | ||
throw new ArgumentNullException(nameof(app)); | ||
} | ||
|
||
if (options == null) { | ||
throw new ArgumentNullException(nameof(options)); | ||
} | ||
|
||
return app.UseMiddleware<SalesforceAuthenticationMiddleware>(Options.Create(options)); | ||
} | ||
|
||
/// <summary> | ||
/// Adds the <see cref="SalesforceAuthenticationMiddleware"/> middleware to the specified | ||
/// <see cref="IApplicationBuilder"/>, which enables Salesforce authentication capabilities. | ||
/// </summary> | ||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param> | ||
/// <param name="configuration">An action delegate to configure the provided <see cref="SalesforceAuthenticationOptions"/>.</param> | ||
/// <returns>A reference to this instance after the operation has completed.</returns> | ||
public static IApplicationBuilder UseSalesforceAuthentication( | ||
[NotNull] this IApplicationBuilder app, | ||
[NotNull] Action<SalesforceAuthenticationOptions> configuration) { | ||
if (app == null) { | ||
throw new ArgumentNullException(nameof(app)); | ||
} | ||
|
||
if (configuration == null) { | ||
throw new ArgumentNullException(nameof(configuration)); | ||
} | ||
|
||
var options = new SalesforceAuthenticationOptions(); | ||
configuration(options); | ||
|
||
return app.UseMiddleware<SalesforceAuthenticationMiddleware>(Options.Create(options)); | ||
} | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using System.Net.Http; | ||
using System.Net.Http.Headers; | ||
using System.Security.Claims; | ||
using System.Threading.Tasks; | ||
using AspNet.Security.OAuth.Extensions; | ||
using JetBrains.Annotations; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Authentication.OAuth; | ||
using Microsoft.AspNetCore.Http.Authentication; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
public class SalesforceAuthenticationHandler : OAuthHandler<SalesforceAuthenticationOptions> { | ||
public SalesforceAuthenticationHandler([NotNull] HttpClient client) | ||
: base(client) { | ||
} | ||
|
||
protected override async Task<AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity, | ||
[NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) { | ||
// Note: unlike the other social providers, the userinfo endpoint is user-specific and can't be set globally. | ||
// For more information, see https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com | ||
var request = new HttpRequestMessage(HttpMethod.Get, tokens.Response.Value<string>("id")); | ||
|
||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken); | ||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); | ||
|
||
var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted); | ||
if (!response.IsSuccessStatusCode) { | ||
Logger.LogError("An error occurred when retrieving the user profile: the remote server " + | ||
"returned a {Status} response with the following payload: {Headers} {Body}.", | ||
/* Status: */ response.StatusCode, | ||
/* Headers: */ response.Headers.ToString(), | ||
/* Body: */ await response.Content.ReadAsStringAsync()); | ||
|
||
throw new HttpRequestException("An error occurred when retrieving the user from the Salesforce identity service."); | ||
} | ||
|
||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); | ||
|
||
identity.AddOptionalClaim(ClaimTypes.NameIdentifier, SalesforceAuthenticationHelper.GetUserIdentifier(payload), Options.ClaimsIssuer) | ||
.AddOptionalClaim(ClaimTypes.Name, SalesforceAuthenticationHelper.GetUserName(payload), Options.ClaimsIssuer) | ||
.AddOptionalClaim("urn:salesforce:email", SalesforceAuthenticationHelper.GetEmail(payload), Options.ClaimsIssuer) | ||
.AddOptionalClaim("urn:salesforce:thumbnail_photo", SalesforceAuthenticationHelper.GetThumbnailPhoto(payload), Options.ClaimsIssuer) | ||
.AddOptionalClaim("urn:salesforce:utc_offset", SalesforceAuthenticationHelper.GetUtcOffset(payload).ToString(), Options.ClaimsIssuer) | ||
.AddOptionalClaim("urn:salesforce:rest_url", SalesforceAuthenticationHelper.GetRestUrl(payload), Options.ClaimsIssuer); | ||
|
||
var principal = new ClaimsPrincipal(identity); | ||
var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme); | ||
|
||
var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload); | ||
await Options.Events.CreatingTicket(context); | ||
|
||
return context.Ticket; | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using JetBrains.Annotations; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
/// <summary> | ||
/// Contains static methods that allow to extract user's information from a <see cref="JObject"/> | ||
/// instance retrieved from Salesforce after a successful authentication process. | ||
/// </summary> | ||
public static class SalesforceAuthenticationHelper { | ||
/// <summary> | ||
/// Gets the Salesforce ID corresponding to the authenticated user. | ||
/// </summary> | ||
public static string GetUserIdentifier([NotNull] JObject user) => user.Value<string>("user_id"); | ||
|
||
/// <summary> | ||
/// Gets the user's name. | ||
/// </summary> | ||
public static string GetUserName([NotNull] JObject user) => user.Value<string>("user_name"); | ||
|
||
/// <summary> | ||
/// Gets the user's email. | ||
/// </summary> | ||
public static string GetEmail([NotNull] JObject user) => user.Value<string>("email"); | ||
|
||
/// <summary> | ||
/// Gets the user's thumbnail photo. | ||
/// </summary> | ||
public static string GetThumbnailPhoto([NotNull] JObject user) => user["photos"]?.Value<string>("thumbnail"); | ||
|
||
/// <summary> | ||
/// Gets the user's UTC offset, in milliseconds. | ||
/// </summary> | ||
public static int GetUtcOffset([NotNull] JObject user) => user.Value<int>("utcOffset"); | ||
|
||
/// <summary> | ||
/// Gets the REST URL returned from the identity service. | ||
/// </summary> | ||
public static string GetRestUrl([NotNull] JObject user) => user["urls"]?.Value<string>("rest"); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using System.Text.Encodings.Web; | ||
using JetBrains.Annotations; | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Authentication.OAuth; | ||
using Microsoft.AspNetCore.DataProtection; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
public class SalesforceAuthenticationMiddleware : OAuthMiddleware<SalesforceAuthenticationOptions> { | ||
public SalesforceAuthenticationMiddleware( | ||
[NotNull] RequestDelegate next, | ||
[NotNull] IOptions<SalesforceAuthenticationOptions> options, | ||
[NotNull] IDataProtectionProvider dataProtectionProvider, | ||
[NotNull] ILoggerFactory loggerFactory, | ||
[NotNull] UrlEncoder encoder, | ||
[NotNull] IOptions<SharedAuthenticationOptions> externalOptions) | ||
: base(next, dataProtectionProvider, loggerFactory, encoder, externalOptions, options) { | ||
} | ||
|
||
protected override AuthenticationHandler<SalesforceAuthenticationOptions> CreateHandler() { | ||
return new SalesforceAuthenticationHandler(Backchannel); | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/AspNet.Security.OAuth.Salesforce/SalesforceAuthenticationOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) | ||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers | ||
* for more information concerning the license and the contributors participating to this project. | ||
*/ | ||
|
||
using System; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace AspNet.Security.OAuth.Salesforce { | ||
/// <summary> | ||
/// Defines a set of options used by <see cref="SalesforceAuthenticationHandler"/>. | ||
/// </summary> | ||
public class SalesforceAuthenticationOptions : OAuthOptions { | ||
public SalesforceAuthenticationOptions() { | ||
AuthenticationScheme = SalesforceAuthenticationDefaults.AuthenticationScheme; | ||
DisplayName = SalesforceAuthenticationDefaults.DisplayName; | ||
ClaimsIssuer = SalesforceAuthenticationDefaults.Issuer; | ||
|
||
CallbackPath = new PathString(SalesforceAuthenticationDefaults.CallbackPath); | ||
|
||
Environment = SalesforceAuthenticationDefaults.Environment; | ||
} | ||
|
||
public SalesforceAuthenticationEnvironment Environment { | ||
set { | ||
switch (value) { | ||
case SalesforceAuthenticationEnvironment.Production: | ||
AuthorizationEndpoint = SalesforceAuthenticationDefaults.Production.AuthorizationEndpoint; | ||
TokenEndpoint = SalesforceAuthenticationDefaults.Production.TokenEndpoint; | ||
break; | ||
|
||
case SalesforceAuthenticationEnvironment.Test: | ||
AuthorizationEndpoint = SalesforceAuthenticationDefaults.Test.AuthorizationEndpoint; | ||
TokenEndpoint = SalesforceAuthenticationDefaults.Test.TokenEndpoint; | ||
break; | ||
|
||
default: | ||
throw new ArgumentOutOfRangeException(nameof(value), value, "Unsupported Salesforce environment"); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.