Compare commits

...

5 Commits

Author SHA1 Message Date
Tommy Parnell
29be30bfd7 bump version 2017-12-29 01:58:14 -05:00
Tommy Parnell
b8055739ff rm semicolon 2017-12-29 01:57:41 -05:00
Ștefan Negrițoiu
7aeca07f08 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
2017-12-29 01:56:14 -05:00
Tommy Parnell
fde4b5ebac fix rake 2017-12-08 11:20:09 -05:00
Tommy Parnell
d5b81fae9c fix sln 2017-12-08 10:51:14 -05:00
9 changed files with 150 additions and 29 deletions

View File

@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
VisualStudioVersion = 15.0.26730.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.ArcGISOnline", "src\Owin.Security.Providers.ArcGISOnline\Owin.Security.Providers.ArcGISOnline.csproj", "{8A49FAEF-D365-4D25-942C-1CAD03845A5E}"
EndProject
@@ -108,10 +108,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.Eve
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.WSO2", "src\Owin.Security.Providers.WSO2\Owin.Security.Providers.WSO2.csproj", "{8FD3A9CB-E684-42C0-A8BF-7746FDD3D43C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.ArcGISPortal", "src\Owin.Security.Providers.ArcGISPortal\Owin.Security.Providers.ArcGISPortal.csproj", "{18547CA4-D7D3-43C2-81C2-A21FC8151A93}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.Podbean", "src\Owin.Security.Providers.Podbean\Owin.Security.Providers.Podbean.csproj", "{A7B95FD4-08AD-499F-B574-07560CC2A63F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.ArcGISPortal", "src\Owin.Security.Providers.ArcGISPortal\Owin.Security.Providers.ArcGISPortal.csproj", "{18547CA4-D7D3-43C2-81C2-A21FC8151A93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -334,12 +334,15 @@ Global
{A7B95FD4-08AD-499F-B574-07560CC2A63F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7B95FD4-08AD-499F-B574-07560CC2A63F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7B95FD4-08AD-499F-B574-07560CC2A63F}.Release|Any CPU.Build.0 = Release|Any CPU
{18547CA4-D7D3-43C2-81C2-A21FC8151A93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18547CA4-D7D3-43C2-81C2-A21FC8151A93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18547CA4-D7D3-43C2-81C2-A21FC8151A93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18547CA4-D7D3-43C2-81C2-A21FC8151A93}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EDFDB942-6583-4AD9-A868-B354B5BF07FC}
EndGlobalSection
EndGlobal

View File

@@ -126,14 +126,50 @@ namespace OwinOAuthProvidersDemo
// clientId: "",
// clientSecret: "");
//in scenarios where a sandbox URL needs to be used
//var salesforceOptions = new SalesforceAuthenticationOptions
// Salesforce Option 1: don't specify explicit Endpoint config and use Production endpoint defaults
//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 =
// new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
// {
// AuthorizationEndpoint =
// "https://ap1.salesforce.com/services/oauth2/authorize",
// Environment = Owin.Security.Providers.Salesforce.Constants.SandboxEnvironment
// },
// 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"
// },
// ClientId = "",
@@ -148,7 +184,7 @@ namespace OwinOAuthProvidersDemo
// }
// }
//};
//app.UseSalesforceAuthentication(salesforceOptions);
//app.UseSalesforceAuthentication(salesforceOptions1);
////app.UseShopifyAuthentication("", "");

View File

@@ -419,6 +419,13 @@ namespace OwinOAuthProvidersDemo.Controllers
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);
}
}

View File

@@ -259,14 +259,14 @@
<Project>{4fd7b873-1994-4990-aa40-c37060121494}</Project>
<Name>Owin.Security.Providers.OpenIDBase</Name>
</ProjectReference>
<ProjectReference Include="..\src\Owin.Security.Providers.ArcGISPortal\Owin.Security.Providers.ArcGISPortal.csproj">
<Project>{18547ca4-d7d3-43c2-81c2-a21fc8151a93}</Project>
<Name>Owin.Security.Providers.ArcGISPortal</Name>
</ProjectReference>
<ProjectReference Include="..\src\Owin.Security.Providers.ArcGISOnline\Owin.Security.Providers.ArcGISOnline.csproj">
<Project>{8a49faef-d365-4d25-942c-1cad03845a5e}</Project>
<Name>Owin.Security.Providers.ArcGISOnline</Name>
</ProjectReference>
<ProjectReference Include="..\src\Owin.Security.Providers.ArcGISPortal\Owin.Security.Providers.ArcGISPortal.csproj">
<Project>{18547ca4-d7d3-43c2-81c2-a21fc8151a93}</Project>
<Name>Owin.Security.Providers.ArcGISPortal</Name>
</ProjectReference>
<ProjectReference Include="..\src\Owin.Security.Providers.Asana\Owin.Security.Providers.Asana.csproj">
<Project>{f3e27220-1d8c-4037-94aa-7b7f4a12f351}</Project>
<Name>Owin.Security.Providers.Asana</Name>

View File

@@ -15,7 +15,7 @@ PACKAGES = File.expand_path("packages")
TOOLS = File.expand_path("tools")
NUGET = File.expand_path("#{TOOLS}/nuget")
NUGET_EXE = File.expand_path("#{TOOLS}/nuget/nuget.exe")
@version = "2.18.0"
@version = "2.19.0"
PROJECTS = Dir.glob('src/*').select{|dir| File.directory? dir }
desc 'Retrieve things'
@@ -70,8 +70,8 @@ desc 'publish nugets'
task :nuspec_publish do
PROJECTS.each{|dir|
Dir.chdir(dir) do
sh "#{NUGET_EXE} push #{FileList["*.nupkg"].first}"
sh "#{NUGET_EXE} push -Source https://api.nuget.org/v3/index.json #{FileList["*.nupkg"].first}"
end
}
sh "#{NUGET_EXE} push #{FileList["*.nupkg"].first}"
sh "#{NUGET_EXE} push -Source https://api.nuget.org/v3/index.json #{FileList["*.nupkg"].first}"
end

View File

@@ -10,12 +10,12 @@ namespace :nuget do
begin
FileUtils.mkdir_p("#{NUGET}")
File.open("#{NUGET}/nuget.exe", "wb") do |file|
file.write open('http://nuget.org/nuget.exe', {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read
file.write open('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read
end
rescue
FileUtils.rm_rf("#{NUGET}/nuget.exe")
File.open("#{NUGET}/nuget.exe", "wb") do |file|
file.write open('https://dist.nuget.org/win-x86-commandline/v3.2.0/nuget.exe', {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read
file.write open('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read
end
end
end

View File

@@ -1,7 +1,11 @@
namespace Owin.Security.Providers.Salesforce
{
internal static class Constants
public static class Constants
{
public const string DefaultAuthenticationType = "Salesforce";
public const string EnvironmentAuthenticationProperty = "Environment";
public const string ProductionEnvironment = "Production";
public const string SandboxEnvironment = "Sandbox";
}
}

View File

@@ -18,6 +18,12 @@ namespace Owin.Security.Providers.Salesforce
{
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 HttpClient _httpClient;
@@ -74,7 +80,7 @@ namespace Owin.Security.Providers.Salesforce
};
// 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.Content = new FormUrlEncodedContent(body);
var tokenResponse = await _httpClient.SendAsync(requestMessage);
@@ -186,8 +192,10 @@ namespace Owin.Security.Providers.Salesforce
var state = Options.StateDataFormat.Protect(properties);
var authorizationEndpoint =
$"{Options.Endpoints.AuthorizationEndpoint}?response_type={"code"}&client_id={Options.ClientId}&redirect_uri={HttpUtility.UrlEncode(redirectUri)}&display={"page"}&immediate={false}&state={Uri.EscapeDataString(state)}";
var authorizationEndpoint = ComposeAuthorizationEndpoint(properties);
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)
{
@@ -253,5 +261,66 @@ namespace Owin.Security.Providers.Salesforce
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;
}
}
}

View File

@@ -19,10 +19,12 @@ namespace Owin.Security.Providers.Salesforce
/// Endpoint which is used to exchange code for access token
/// </summary>
public string TokenEndpoint { get; set; }
}
private const string AuthorizationEndPoint = "";
private const string TokenEndpoint = "";
/// <summary>
/// Production or Sandbox. Use Constants.ProductionEnvironment or Constants.SandboxEnvironment
/// </summary>
public string Environment { get; set; }
}
/// <summary>
/// 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; }
/// <summary>
/// Gets the sets of OAuth endpoints used to authenticate against Salesforce. Overriding these endpoints allows you to use Salesforce Enterprise for
/// authentication.
/// Gets the sets of OAuth endpoints used to authenticate against Salesforce.
/// Overriding these endpoints allows you to use Salesforce Enterprise for authentication.
/// </summary>
public SalesforceAuthenticationEndpoints Endpoints { get; set; }
@@ -127,8 +129,8 @@ namespace Owin.Security.Providers.Salesforce
BackchannelTimeout = TimeSpan.FromSeconds(60);
Endpoints = new SalesforceAuthenticationEndpoints
{
AuthorizationEndpoint = AuthorizationEndPoint,
TokenEndpoint = TokenEndpoint
AuthorizationEndpoint = null,
TokenEndpoint = null
};
}
}