Salesforce provider: add Option to specify Production vs. Sandbox environment (#223)
* add Option to specify Production vs. Sandbox Environment also fixes issue https://github.com/TerribleDev/OwinOAuthProviders/issues/54 * ability to specify Production vs. Sandbox environment per auth session in addition to global setting * add examples to show usage of new Production vs. Sandbox Option for Salesforce provider
This commit is contained in:
committed by
Tommy Parnell
parent
fde4b5ebac
commit
7aeca07f08
@@ -126,14 +126,50 @@ namespace OwinOAuthProvidersDemo
|
|||||||
// clientId: "",
|
// clientId: "",
|
||||||
// clientSecret: "");
|
// clientSecret: "");
|
||||||
|
|
||||||
//in scenarios where a sandbox URL needs to be used
|
// Salesforce Option 1: don't specify explicit Endpoint config and use Production endpoint defaults
|
||||||
//var salesforceOptions = new SalesforceAuthenticationOptions
|
//var salesforceOptions1 = new SalesforceAuthenticationOptions
|
||||||
|
//{
|
||||||
|
// ClientId = "",
|
||||||
|
// ClientSecret = "",
|
||||||
|
// Provider = new SalesforceAuthenticationProvider()
|
||||||
|
// {
|
||||||
|
// OnAuthenticated = async context =>
|
||||||
|
// {
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.AccessToken);
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.RefreshToken);
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.OrganizationId);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
// Salesforce Option 2: ask for Sandbox environment; no need to know what those endpoints are
|
||||||
|
//var salesforceOptions2 = new SalesforceAuthenticationOptions
|
||||||
//{
|
//{
|
||||||
// Endpoints =
|
// Endpoints =
|
||||||
// new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
|
// new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
|
||||||
// {
|
// {
|
||||||
// AuthorizationEndpoint =
|
// Environment = Owin.Security.Providers.Salesforce.Constants.SandboxEnvironment
|
||||||
// "https://ap1.salesforce.com/services/oauth2/authorize",
|
// },
|
||||||
|
// ClientId = "",
|
||||||
|
// ClientSecret = "",
|
||||||
|
// Provider = new SalesforceAuthenticationProvider()
|
||||||
|
// {
|
||||||
|
// OnAuthenticated = async context =>
|
||||||
|
// {
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.AccessToken);
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.RefreshToken);
|
||||||
|
// System.Diagnostics.Debug.WriteLine(context.OrganizationId);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
// Salesforce Option 3: explicitly specify endpoints (will take precedence over Environment choice)
|
||||||
|
//var salesforceOptions3 = new SalesforceAuthenticationOptions
|
||||||
|
//{
|
||||||
|
// Endpoints =
|
||||||
|
// new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
|
||||||
|
// {
|
||||||
|
// AuthorizationEndpoint = "https://ap1.salesforce.com/services/oauth2/authorize",
|
||||||
// TokenEndpoint = "https://ap1.salesforce.com/services/oauth2/token"
|
// TokenEndpoint = "https://ap1.salesforce.com/services/oauth2/token"
|
||||||
// },
|
// },
|
||||||
// ClientId = "",
|
// ClientId = "",
|
||||||
@@ -148,7 +184,7 @@ namespace OwinOAuthProvidersDemo
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//};
|
//};
|
||||||
//app.UseSalesforceAuthentication(salesforceOptions);
|
//app.UseSalesforceAuthentication(salesforceOptions1);
|
||||||
|
|
||||||
////app.UseShopifyAuthentication("", "");
|
////app.UseShopifyAuthentication("", "");
|
||||||
|
|
||||||
|
|||||||
@@ -419,6 +419,13 @@ namespace OwinOAuthProvidersDemo.Controllers
|
|||||||
properties.Dictionary[ShopNameKey] = ShopName;
|
properties.Dictionary[ShopNameKey] = ShopName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if use Salesforce as OAuth provider you can ask for Sandbox auth endpoint
|
||||||
|
// for this particular request only
|
||||||
|
//properties.Dictionary.Add(
|
||||||
|
// Owin.Security.Providers.Salesforce.Constants.EnvironmentAuthenticationProperty,
|
||||||
|
// Owin.Security.Providers.Salesforce.Constants.SandboxEnvironment
|
||||||
|
// );
|
||||||
|
|
||||||
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
|
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
namespace Owin.Security.Providers.Salesforce
|
namespace Owin.Security.Providers.Salesforce
|
||||||
{
|
{
|
||||||
internal static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const string DefaultAuthenticationType = "Salesforce";
|
public const string DefaultAuthenticationType = "Salesforce";
|
||||||
|
|
||||||
|
public const string EnvironmentAuthenticationProperty = "Environment";
|
||||||
|
public const string ProductionEnvironment = "Production";
|
||||||
|
public const string SandboxEnvironment = "Sandbox";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,12 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
{
|
{
|
||||||
private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
|
private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
|
||||||
|
|
||||||
|
private const string ProductionHost = "https://login.salesforce.com";
|
||||||
|
private const string SandboxHost = "https://test.salesforce.com";
|
||||||
|
|
||||||
|
private const string AuthorizationEndpoint = "/services/oauth2/authorize";
|
||||||
|
private const string TokenEndpoint = "/services/oauth2/token";
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
@@ -74,7 +80,7 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Request the token
|
// Request the token
|
||||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.Endpoints.TokenEndpoint);
|
var requestMessage = new HttpRequestMessage(HttpMethod.Post, ComposeTokenEndpoint(properties));
|
||||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
requestMessage.Content = new FormUrlEncodedContent(body);
|
requestMessage.Content = new FormUrlEncodedContent(body);
|
||||||
var tokenResponse = await _httpClient.SendAsync(requestMessage);
|
var tokenResponse = await _httpClient.SendAsync(requestMessage);
|
||||||
@@ -186,8 +192,10 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
|
|
||||||
var state = Options.StateDataFormat.Protect(properties);
|
var state = Options.StateDataFormat.Protect(properties);
|
||||||
|
|
||||||
var authorizationEndpoint =
|
var authorizationEndpoint = ComposeAuthorizationEndpoint(properties);
|
||||||
$"{Options.Endpoints.AuthorizationEndpoint}?response_type={"code"}&client_id={Options.ClientId}&redirect_uri={HttpUtility.UrlEncode(redirectUri)}&display={"page"}&immediate={false}&state={Uri.EscapeDataString(state)}";
|
|
||||||
|
authorizationEndpoint =
|
||||||
|
$"{authorizationEndpoint}?response_type={"code"}&client_id={Options.ClientId}&redirect_uri={HttpUtility.UrlEncode(redirectUri)}&display={"page"}&immediate={false}&state={Uri.EscapeDataString(state)}";
|
||||||
|
|
||||||
if (Options.Scope != null && Options.Scope.Count > 0)
|
if (Options.Scope != null && Options.Scope.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -253,5 +261,66 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
|
|
||||||
return context.IsRequestCompleted;
|
return context.IsRequestCompleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string ComposeAuthorizationEndpoint(AuthenticationProperties properties) {
|
||||||
|
string endpointPath = AuthorizationEndpoint;
|
||||||
|
|
||||||
|
string endpoint =
|
||||||
|
!String.IsNullOrEmpty(Options.Endpoints.AuthorizationEndpoint) ?
|
||||||
|
Options.Endpoints.AuthorizationEndpoint :
|
||||||
|
ComposeEndpoint(properties, endpointPath);
|
||||||
|
|
||||||
|
// if AuthenticationProperties for this session specifies an environment property
|
||||||
|
// it should take precedence over the value in AuthenticationOptions
|
||||||
|
string environmentProperty = null; ;
|
||||||
|
if (properties.Dictionary.TryGetValue(Constants.EnvironmentAuthenticationProperty, out environmentProperty)) {
|
||||||
|
endpoint =
|
||||||
|
environmentProperty == Constants.SandboxEnvironment ?
|
||||||
|
SandboxHost + endpointPath :
|
||||||
|
ProductionHost + endpointPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ComposeTokenEndpoint(AuthenticationProperties properties) {
|
||||||
|
string endpointPath = TokenEndpoint;
|
||||||
|
|
||||||
|
string endpoint =
|
||||||
|
!String.IsNullOrEmpty(Options.Endpoints.TokenEndpoint) ?
|
||||||
|
Options.Endpoints.TokenEndpoint :
|
||||||
|
ComposeEndpoint(properties, endpointPath);
|
||||||
|
|
||||||
|
// if AuthenticationProperties for this session specifies an environment property
|
||||||
|
// it should take precedence over the value in AuthenticationOptions
|
||||||
|
string environmentProperty = null; ;
|
||||||
|
if (properties.Dictionary.TryGetValue(Constants.EnvironmentAuthenticationProperty, out environmentProperty)) {
|
||||||
|
endpoint =
|
||||||
|
environmentProperty == Constants.SandboxEnvironment ?
|
||||||
|
SandboxHost + endpointPath :
|
||||||
|
ProductionHost + endpointPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ComposeEndpoint(AuthenticationProperties properties, string endpointPath) {
|
||||||
|
string endpoint =
|
||||||
|
!String.IsNullOrEmpty(Options.Endpoints.Environment) && Options.Endpoints.Environment == Constants.SandboxEnvironment ?
|
||||||
|
SandboxHost + endpointPath :
|
||||||
|
ProductionHost + endpointPath;
|
||||||
|
|
||||||
|
// if AuthenticationProperties for this session specifies an environment property
|
||||||
|
// it should take precedence over the value in AuthenticationOptions
|
||||||
|
string environmentProperty = null; ;
|
||||||
|
if (properties.Dictionary.TryGetValue(Constants.EnvironmentAuthenticationProperty, out environmentProperty)) {
|
||||||
|
endpoint =
|
||||||
|
environmentProperty == Constants.SandboxEnvironment ?
|
||||||
|
SandboxHost + endpointPath :
|
||||||
|
ProductionHost + endpointPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
/// Endpoint which is used to exchange code for access token
|
/// Endpoint which is used to exchange code for access token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TokenEndpoint { get; set; }
|
public string TokenEndpoint { get; set; }
|
||||||
}
|
|
||||||
|
|
||||||
private const string AuthorizationEndPoint = "";
|
/// <summary>
|
||||||
private const string TokenEndpoint = "";
|
/// Production or Sandbox. Use Constants.ProductionEnvironment or Constants.SandboxEnvironment
|
||||||
|
/// </summary>
|
||||||
|
public string Environment { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the a pinned certificate validator to use to validate the endpoints used
|
/// Gets or sets the a pinned certificate validator to use to validate the endpoints used
|
||||||
@@ -79,8 +81,8 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
public string ClientSecret { get; set; }
|
public string ClientSecret { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the sets of OAuth endpoints used to authenticate against Salesforce. Overriding these endpoints allows you to use Salesforce Enterprise for
|
/// Gets the sets of OAuth endpoints used to authenticate against Salesforce.
|
||||||
/// authentication.
|
/// Overriding these endpoints allows you to use Salesforce Enterprise for authentication.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SalesforceAuthenticationEndpoints Endpoints { get; set; }
|
public SalesforceAuthenticationEndpoints Endpoints { get; set; }
|
||||||
|
|
||||||
@@ -127,8 +129,8 @@ namespace Owin.Security.Providers.Salesforce
|
|||||||
BackchannelTimeout = TimeSpan.FromSeconds(60);
|
BackchannelTimeout = TimeSpan.FromSeconds(60);
|
||||||
Endpoints = new SalesforceAuthenticationEndpoints
|
Endpoints = new SalesforceAuthenticationEndpoints
|
||||||
{
|
{
|
||||||
AuthorizationEndpoint = AuthorizationEndPoint,
|
AuthorizationEndpoint = null,
|
||||||
TokenEndpoint = TokenEndpoint
|
TokenEndpoint = null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user