diff --git a/.gitignore b/.gitignore
index 12792ed..b3aafc2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,14 +11,15 @@
*.sln.docstates
# Build results
-
+.gitignore/
+.bundle/
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
-
+OwinOAuthProvidersDemo/App_Data/
# Visual Studo 2015 cache/options directory
.vs/
Owin.Security.Providers.nuspec
diff --git a/Gemfile.lock b/Gemfile.lock
index a65d7e6..71308d0 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -21,7 +21,6 @@ DEPENDENCIES
albacore
nokogiri
os
- rake
BUNDLED WITH
- 1.10.6
+ 1.12.1
diff --git a/OwinOAuthProviders.sln b/OwinOAuthProviders.sln
index 5178cf3..6141d54 100644
--- a/OwinOAuthProviders.sln
+++ b/OwinOAuthProviders.sln
@@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OwinOAuthProvidersDemo", "OwinOAuthProvidersDemo\OwinOAuthProvidersDemo.csproj", "{5A438007-0C90-4DAC-BAA1-54A32164067F}"
-EndProject
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
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.Asana", "src\Owin.Security.Providers.Asana\Owin.Security.Providers.Asana.csproj", "{F3E27220-1D8C-4037-94AA-7B7F4A12F351}"
@@ -92,16 +90,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.Ope
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.SlackProvider", "src\Owin.Security.Providers.SlackProvider\Owin.Security.Providers.SlackProvider.csproj", "{3E6F293D-8500-428D-BDC9-27440CC91E16}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.Providers.Orcid", "src\Owin.Security.Providers.Orcid\Owin.Security.Providers.Orcid.csproj", "{89CB4342-E23D-4E7C-89E5-C369599A5860}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OwinOAuthProvidersDemo", "OwinOAuthProvidersDemo\OwinOAuthProvidersDemo.csproj", "{5A438007-0C90-4DAC-BAA1-54A32164067F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5A438007-0C90-4DAC-BAA1-54A32164067F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5A438007-0C90-4DAC-BAA1-54A32164067F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5A438007-0C90-4DAC-BAA1-54A32164067F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5A438007-0C90-4DAC-BAA1-54A32164067F}.Release|Any CPU.Build.0 = Release|Any CPU
{8A49FAEF-D365-4D25-942C-1CAD03845A5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A49FAEF-D365-4D25-942C-1CAD03845A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A49FAEF-D365-4D25-942C-1CAD03845A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -278,6 +276,14 @@ Global
{3E6F293D-8500-428D-BDC9-27440CC91E16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E6F293D-8500-428D-BDC9-27440CC91E16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E6F293D-8500-428D-BDC9-27440CC91E16}.Release|Any CPU.Build.0 = Release|Any CPU
+ {89CB4342-E23D-4E7C-89E5-C369599A5860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {89CB4342-E23D-4E7C-89E5-C369599A5860}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {89CB4342-E23D-4E7C-89E5-C369599A5860}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {89CB4342-E23D-4E7C-89E5-C369599A5860}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A438007-0C90-4DAC-BAA1-54A32164067F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A438007-0C90-4DAC-BAA1-54A32164067F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A438007-0C90-4DAC-BAA1-54A32164067F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A438007-0C90-4DAC-BAA1-54A32164067F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
index 75ddad9..dd040c8 100755
--- a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
+++ b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
@@ -3,278 +3,279 @@ using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
+//using Owin.Security.Providers.Orcid;
+
namespace OwinOAuthProvidersDemo
{
- public partial class Startup
- {
- // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
- public void ConfigureAuth(IAppBuilder app)
- {
- // Enable the application to use a cookie to store information for the signed in user
- app.UseCookieAuthentication(new CookieAuthenticationOptions
- {
- AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
- LoginPath = new PathString("/Account/Login")
- });
- // Use a cookie to temporarily store information about a user logging in with a third party login provider
- app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
- //app.UseDeviantArtAuthentication("id", "secret");
- //app.UseUntappdAuthentication("id", "secret");
- // Uncomment the following lines to enable logging in with third party login providers
- //app.UseMicrosoftAccountAuthentication(
- // clientId: "",
- // clientSecret: "");
+ public partial class Startup
+ {
+ // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
+ public void ConfigureAuth(IAppBuilder app)
+ {
+ // Enable the application to use a cookie to store information for the signed in user
+ app.UseCookieAuthentication(new CookieAuthenticationOptions
+ {
+ AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
+ LoginPath = new PathString("/Account/Login")
+ });
+ // Use a cookie to temporarily store information about a user logging in with a third party login provider
+ app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
+ //app.UseDeviantArtAuthentication("id", "secret");
+ //app.UseUntappdAuthentication("id", "secret");
+ // Uncomment the following lines to enable logging in with third party login providers
+ //app.UseMicrosoftAccountAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseTwitterAuthentication(
- // consumerKey: "",
- // consumerSecret: "");
+ //app.UseTwitterAuthentication(
+ // consumerKey: "",
+ // consumerSecret: "");
- //app.UseFacebookAuthentication(
- // appId: "",
- // appSecret: "");
+ //app.UseFacebookAuthentication(
+ // appId: "",
+ // appSecret: "");
- //app.UseGoogleAuthentication();
+ //app.UseGoogleAuthentication();
- //app.UseLinkedInAuthentication("", "");
+ //app.UseLinkedInAuthentication("", "");
- //app.UseYahooAuthentication("", "");
+ //app.UseYahooAuthentication("", "");
- //app.UseTripItAuthentication("", "");
+ //app.UseTripItAuthentication("", "");
- //app.UseGitHubAuthentication("", "");
+ //app.UseGitHubAuthentication("", "");
- //app.UseBufferAuthentication("", "");
+ //app.UseBufferAuthentication("", "");
- //app.UseRedditAuthentication("", "");
+ //app.UseRedditAuthentication("", "");
- //app.UseStackExchangeAuthentication(
- // clientId: "",
- // clientSecret: "",
- // key: "");
+ //app.UseStackExchangeAuthentication(
+ // clientId: "",
+ // clientSecret: "",
+ // key: "");
- //app.UseInstagramInAuthentication("", "");
+ //app.UseInstagramInAuthentication("", "");
- //var options = new GooglePlusAuthenticationOptions
- //{
- // ClientId = "",
- // ClientSecret = "",
- // RequestOfflineAccess = true,
- // Provider = new GooglePlusAuthenticationProvider
- // {
- // OnAuthenticated = async context => System.Diagnostics.Debug.WriteLine(String.Format("Refresh Token: {0}", context.RefreshToken))
- // }
- //};
- //options.MomentTypes.Add("http://schemas.google.com/AddActivity");
- //options.MomentTypes.Add("http://schemas.google.com/CheckInActivity");
- //options.MomentTypes.Add("http://schemas.google.com/BuyActivity");
- //app.UseGooglePlusAuthentication(options);
+ //var options = new GooglePlusAuthenticationOptions
+ //{
+ // ClientId = "",
+ // ClientSecret = "",
+ // RequestOfflineAccess = true,
+ // Provider = new GooglePlusAuthenticationProvider
+ // {
+ // OnAuthenticated = async context => System.Diagnostics.Debug.WriteLine(String.Format("Refresh Token: {0}", context.RefreshToken))
+ // }
+ //};
+ //options.MomentTypes.Add("http://schemas.google.com/AddActivity");
+ //options.MomentTypes.Add("http://schemas.google.com/CheckInActivity");
+ //options.MomentTypes.Add("http://schemas.google.com/BuyActivity");
+ //app.UseGooglePlusAuthentication(options);
- /*
+ /*
* Twitch sign-ins use /signin-Twitch as the URL for authentication
- *
-
+ *
+
*/
- ////Simple Twitch Sign-in
- //app.UseTwitchAuthentication("", "");
+ ////Simple Twitch Sign-in
+ //app.UseTwitchAuthentication("", "");
- ////More complex Twitch Sign-in
- //var opt = new TwitchAuthenticationOptions()
- //{
- // ClientId = "",
- // ClientSecret = "",
- // Provider = new TwitchAuthenticationProvider()
- // {
+ ////More complex Twitch Sign-in
+ //var opt = new TwitchAuthenticationOptions()
+ //{
+ // ClientId = "",
+ // ClientSecret = "",
+ // Provider = new TwitchAuthenticationProvider()
+ // {
+ // OnAuthenticated = async z =>
+ // {
+ //// Getting the twitch users picture
+ // z.Identity.AddClaim(new Claim("Picture", z.User.GetValue("logo").ToString()));
+ // }
+ //// You should be able to access these claims with HttpContext.GetOwinContext().Authentication.GetExternalLoginInfoAsync().Claims in your Account Controller
+ // // Commonly used in the ExternalLoginCallback() in AccountController.cs
+ // /*
- // OnAuthenticated = async z =>
- // {
- //// Getting the twitch users picture
- // z.Identity.AddClaim(new Claim("Picture", z.User.GetValue("logo").ToString()));
- // }
- //// You should be able to access these claims with HttpContext.GetOwinContext().Authentication.GetExternalLoginInfoAsync().Claims in your Account Controller
- // // Commonly used in the ExternalLoginCallback() in AccountController.cs
- // /*
+ // if (user != null)
+ // {
+ // var claim = (await AuthenticationManager.GetExternalLoginInfoAsync()).ExternalIdentity.Claims.First(
+ // a => a.Type == "Picture");
+ // user.Claims.Add(new IdentityUserClaim() { ClaimType = claim.Type, ClaimValue = claim.Value });
+ // await SignInAsync(user, isPersistent: false);
+ // return RedirectToLocal(returnUrl);
+ // }
+ // */
+ // }
+ //};
+ //app.UseTwitchAuthentication(opt);
- // if (user != null)
- // {
- // var claim = (await AuthenticationManager.GetExternalLoginInfoAsync()).ExternalIdentity.Claims.First(
- // a => a.Type == "Picture");
- // user.Claims.Add(new IdentityUserClaim() { ClaimType = claim.Type, ClaimValue = claim.Value });
- // await SignInAsync(user, isPersistent: false);
- // return RedirectToLocal(returnUrl);
- // }
- // */
- // }
- //};
- //app.UseTwitchAuthentication(opt);
+ //app.UseOpenIDAuthentication("http://me.yahoo.com/", "Yahoo");
+ //app.UseOpenIDAuthentication("https://openid.stackexchange.com/", "StackExchange");
+ //app.UseOpenIDAuthentication("https://www.google.com/accounts/o8/id", "Google");
- //app.UseOpenIDAuthentication("http://me.yahoo.com/", "Yahoo");
+ //app.UseSteamAuthentication(applicationKey: "");
- //app.UseOpenIDAuthentication("https://openid.stackexchange.com/", "StackExchange");
+ //app.UseOpenIDAuthentication("http://orange.fr", "Orange");
+ // Use OpenId provider login uri instead of discovery uri
+ //app.UseOpenIDAuthentication("http://openid.orange.fr/server", "Orange", true);
- //app.UseOpenIDAuthentication("https://www.google.com/accounts/o8/id", "Google");
+ //app.UseSalesforceAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseSteamAuthentication(applicationKey: "");
+ //in scenarios where a sandbox URL needs to be used
+ //var salesforceOptions = new SalesforceAuthenticationOptions
+ //{
+ // Endpoints =
+ // new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
+ // {
+ // AuthorizationEndpoint =
+ // "https://ap1.salesforce.com/services/oauth2/authorize",
+ // TokenEndpoint = "https://ap1.salesforce.com/services/oauth2/token"
+ // },
+ // 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);
+ // }
+ // }
+ //};
+ //app.UseSalesforceAuthentication(salesforceOptions);
- //app.UseOpenIDAuthentication("http://orange.fr", "Orange");
- // Use OpenId provider login uri instead of discovery uri
- //app.UseOpenIDAuthentication("http://openid.orange.fr/server", "Orange", true);
+ ////app.UseShopifyAuthentication("", "");
- //app.UseSalesforceAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseArcGISOnlineAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //in scenarios where a sandbox URL needs to be used
- //var salesforceOptions = new SalesforceAuthenticationOptions
- //{
- // Endpoints =
- // new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
- // {
- // AuthorizationEndpoint =
- // "https://ap1.salesforce.com/services/oauth2/authorize",
- // TokenEndpoint = "https://ap1.salesforce.com/services/oauth2/token"
- // },
- // 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);
- // }
- // }
- //};
- //app.UseSalesforceAuthentication(salesforceOptions);
+ //app.UseWordPressAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- ////app.UseShopifyAuthentication("", "");
+ //app.UseDropboxAuthentication(
+ // appKey: "",
+ // appSecret: "");
- //app.UseArcGISOnlineAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseHealthGraphAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseWordPressAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseBattleNetAuthentication(new BattleNetAuthenticationOptions
+ //{
+ // ClientId = "",
+ // ClientSecret = ""
+ //});
+ //app.UseBattleNetAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseDropboxAuthentication(
- // appKey: "",
- // appSecret: "");
+ //app.UseAsanaAuthentication("", "");
- //app.UseHealthGraphAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseEveOnlineAuthentication("", "");
- //app.UseBattleNetAuthentication(new BattleNetAuthenticationOptions
- //{
- // ClientId = "",
- // ClientSecret = ""
- //});
- //app.UseBattleNetAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseSoundCloudAuthentication("", "");
- //app.UseAsanaAuthentication("", "");
+ //app.UseFoursquareAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseEveOnlineAuthentication("", "");
+ //app.UsePayPalAuthentication(
+ // clientId: "",
+ // clientSecret: "",
+ // isSandbox: false);
- //app.UseSoundCloudAuthentication("", "");
+ //app.UseWargamingAccountAuthentication("", WargamingAuthenticationOptions.Region.NorthAmerica);
- //app.UseFoursquareAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseFlickrAuthentication("", "");
+ //app.UseVisualStudioAuthentication(
+ // appId: "",
+ // appSecret: "");
- //app.UsePayPalAuthentication(
- // clientId: "",
- // clientSecret: "",
- // isSandbox: false);
+ //app.UseSpotifyAuthentication(
+ // clientId: "",
+ // clientSecret: "");
- //app.UseWargamingAccountAuthentication("", WargamingAuthenticationOptions.Region.NorthAmerica);
+ //var options = new SlackAuthenticationOptions
+ //{
+ // ClientId = "",
+ // ClientSecret = "",
+ // TeamId = "" // optional
+ //};
+ //options.Scope.Add("identify");
+ //app.UseSlackAuthentication(options);
- //app.UseFlickrAuthentication("", "");
- //app.UseVisualStudioAuthentication(
- // appId: "",
- // appSecret: "");
+ //app.UseGitterAuthentication(
+ // clientId: "",
+ // clientSecret: ""
+ //);
- //app.UseSpotifyAuthentication(
- // clientId: "",
- // clientSecret: "");
+ //app.UseImgurAuthentication(
+ // new ImgurAuthenticationOptions
+ // {
+ // ClientId = "",
+ // ClientSecret = ""
+ // });
- //var options = new SlackAuthenticationOptions
- //{
- // ClientId = "",
- // ClientSecret = "",
- // TeamId = "" // optional
- //};
- //options.Scope.Add("identify");
- //app.UseSlackAuthentication(options);
+ //var options = new BacklogAuthenticationOptions
+ //{
+ // ClientId = "",
+ // ClientSecret = "",
+ // ContractName = "",
+ // CallbackPath = new PathString(""), // ex.new PathString("/OauthTokenRequest")
+ // Provider = new BacklogAuthenticationProvider
+ // {
+ // OnAuthenticated = async context => await System.Threading.Tasks.Task.Run(()=> { System.Diagnostics.Debug.WriteLine(String.Format("Refresh Token: {0}", context.RefreshToken)); })
+ // }
+ //};
- //app.UseGitterAuthentication(
- // clientId: "",
- // clientSecret: ""
- //);
+ //app.UseBacklogAuthentication(options);
- //app.UseImgurAuthentication(
- // new ImgurAuthenticationOptions
- // {
- // ClientId = "",
- // ClientSecret = ""
- // });
+ //var cosignOptions = new CosignAuthenticationOptions
+ //{
+ // AuthenticationType = "Cosign",
+ // SignInAsAuthenticationType = signInAsType,
+ // CosignServer = "weblogin.umich.edu",
+ // CosignServicePort = 6663,
+ // IdentityServerHostInstance = "core1",
+ // ClientServer = "cosignservername"
+ //};
+ //app.UseCosignAuthentication(cosignOptions);
- //var options = new BacklogAuthenticationOptions
- //{
- // ClientId = "",
- // ClientSecret = "",
- // ContractName = "",
- // CallbackPath = new PathString(""), // ex.new PathString("/OauthTokenRequest")
- // Provider = new BacklogAuthenticationProvider
- // {
- // OnAuthenticated = async context => await System.Threading.Tasks.Task.Run(()=> { System.Diagnostics.Debug.WriteLine(String.Format("Refresh Token: {0}", context.RefreshToken)); })
- // }
- //};
+ //app.UseVimeoAuthentication("", "");
- //app.UseBacklogAuthentication(options);
+ //app.UseFitbitAuthentication(new FitbitAuthenticationOptions
+ //{
+ // ClientId = "",
+ // ClientSecret = ""
+ //});
- //var cosignOptions = new CosignAuthenticationOptions
- //{
- // AuthenticationType = "Cosign",
- // SignInAsAuthenticationType = signInAsType,
- // CosignServer = "weblogin.umich.edu",
- // CosignServicePort = 6663,
- // IdentityServerHostInstance = "core1",
- // ClientServer = "cosignservername"
- //};
- //app.UseCosignAuthentication(cosignOptions);
+ //app.UseOnshapeAuthentication(
+ // appKey: "",
+ // appSecret: "");
+ //
+ //
+ //app.UseOnshapeAuthentication(new OnshapeAuthenticationOptions()
+ //{
+ // AppKey = "",
+ // AppSecret = "",
+ // CallbackPath = new PathString("/oauthRedirect"),
+ // Hostname = "partner.dev.onshape.com"
+ //});
- //app.UseVimeoAuthentication("", "");
-
- //app.UseFitbitAuthentication(new FitbitAuthenticationOptions
- //{
- // ClientId = "",
- // ClientSecret = ""
- //});
+ //app.UseVKontakteAuthentication("", "");
- //app.UseOnshapeAuthentication(
- // appKey: "",
- // appSecret: "");
- //
- //
- //app.UseOnshapeAuthentication(new OnshapeAuthenticationOptions()
- //{
- // AppKey = "",
- // AppSecret = "",
- // CallbackPath = new PathString("/oauthRedirect"),
- // Hostname = "partner.dev.onshape.com"
- //});
+ //app.UseXingAuthentication("", "");
- //app.UseVKontakteAuthentication("", "");
-
- //app.UseXingAuthentication("", "");
-
- //app.UseDoYouBuzzAuthentication("", "");
- }
- }
-}
+ //app.UseDoYouBuzzAuthentication("", "");
+ //app.("", "");
+ //app.UseOrcidAuthentication("APP-QQ4XO1AYU3WR696B", "6bb22d2e-71b3-4d5d-b1af-f5d3a8cd4270");
+ }
+ }
+}
\ No newline at end of file
diff --git a/OwinOAuthProvidersDemo/OwinOAuthProvidersDemo.csproj b/OwinOAuthProvidersDemo/OwinOAuthProvidersDemo.csproj
index bbaaf3f..2d2c708 100644
--- a/OwinOAuthProvidersDemo/OwinOAuthProvidersDemo.csproj
+++ b/OwinOAuthProvidersDemo/OwinOAuthProvidersDemo.csproj
@@ -13,7 +13,7 @@
Properties
OwinOAuthProvidersDemo
OwinOAuthProvidersDemo
- v4.5
+ v4.5.2
false
true
44300
@@ -21,6 +21,7 @@
disabled
false
+
true
@@ -65,16 +66,16 @@
True
-
- ..\packages\Microsoft.Owin.2.1.0\lib\net45\Microsoft.Owin.dll
+
+ ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
True
..\packages\Microsoft.Owin.Host.SystemWeb.2.1.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
True
-
- ..\packages\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll
+
+ ..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll
True
@@ -105,8 +106,8 @@
..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
True
-
- ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll
True
@@ -115,13 +116,13 @@
+
-
-
+
..\packages\Microsoft.AspNet.WebPages.3.2.0\lib\net45\System.Web.Helpers.dll
True
@@ -150,9 +151,7 @@
..\packages\Microsoft.AspNet.WebPages.3.2.0\lib\net45\System.Web.WebPages.Razor.dll
True
-
-
@@ -163,6 +162,7 @@
+
..\packages\WebGrease.1.6.0\lib\WebGrease.dll
True
diff --git a/OwinOAuthProvidersDemo/Web.config b/OwinOAuthProvidersDemo/Web.config
index dc9e98f..0f5f4a7 100644
--- a/OwinOAuthProvidersDemo/Web.config
+++ b/OwinOAuthProvidersDemo/Web.config
@@ -1,16 +1,15 @@
-
+
-
-
+
@@ -18,9 +17,17 @@
+
-
+
@@ -40,11 +47,11 @@
-
+
-
+
@@ -60,7 +67,7 @@
-
+
diff --git a/OwinOAuthProvidersDemo/packages.config b/OwinOAuthProvidersDemo/packages.config
index d4b92b5..54ead64 100644
--- a/OwinOAuthProvidersDemo/packages.config
+++ b/OwinOAuthProvidersDemo/packages.config
@@ -13,9 +13,9 @@
-
+
-
+
@@ -24,7 +24,7 @@
-
+
diff --git a/README.md b/README.md
index 718641a..f31335f 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@ Provides a set of extra authentication providers for OWIN ([Project Katana](http
- Instagram
- LinkedIn
- Onshape
+ - ORCID
- PayPal
- Reddit
- Salesforce
diff --git a/src/Owin.Security.Providers.Orcid/Constants.cs b/src/Owin.Security.Providers.Orcid/Constants.cs
new file mode 100644
index 0000000..acb1dd2
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/Constants.cs
@@ -0,0 +1,7 @@
+namespace Owin.Security.Providers.Orcid
+{
+ internal static class Constants
+ {
+ public const string DefaultAuthenticationType = "Orcid";
+ }
+}
\ No newline at end of file
diff --git a/src/Owin.Security.Providers.Orcid/Message/OrcidMessage.cs b/src/Owin.Security.Providers.Orcid/Message/OrcidMessage.cs
new file mode 100644
index 0000000..f60bf79
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/Message/OrcidMessage.cs
@@ -0,0 +1,293 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace Owin.Security.Providers.Orcid.Message
+{
+ public class OrcidIdentifier
+ {
+
+ [JsonProperty("value")]
+ public object Value { get; set; }
+
+ [JsonProperty("uri")]
+ public string Uri { get; set; }
+
+ [JsonProperty("path")]
+ public string Path { get; set; }
+
+ [JsonProperty("host")]
+ public string Host { get; set; }
+ }
+
+ public class OrcidPreferences
+ {
+
+ [JsonProperty("locale")]
+ public string Locale { get; set; }
+ }
+
+ public class SubmissionDate
+ {
+
+ [JsonProperty("value")]
+ public long Value { get; set; }
+ }
+
+ public class LastModifiedDate
+ {
+
+ [JsonProperty("value")]
+ public long Value { get; set; }
+ }
+
+ public class Claimed
+ {
+
+ [JsonProperty("value")]
+ public bool Value { get; set; }
+ }
+
+ public class VerifiedEmail
+ {
+
+ [JsonProperty("value")]
+ public bool Value { get; set; }
+ }
+
+ public class VerifiedPrimaryEmail
+ {
+
+ [JsonProperty("value")]
+ public bool Value { get; set; }
+ }
+
+ public class OrcidHistory
+ {
+
+ [JsonProperty("creation-method")]
+ public string CreationMethod { get; set; }
+
+ [JsonProperty("completion-date")]
+ public object CompletionDate { get; set; }
+
+ [JsonProperty("submission-date")]
+ public SubmissionDate SubmissionDate { get; set; }
+
+ [JsonProperty("last-modified-date")]
+ public LastModifiedDate LastModifiedDate { get; set; }
+
+ [JsonProperty("claimed")]
+ public Claimed Claimed { get; set; }
+
+ [JsonProperty("source")]
+ public object Source { get; set; }
+
+ [JsonProperty("deactivation-date")]
+ public object DeactivationDate { get; set; }
+
+ [JsonProperty("verified-email")]
+ public VerifiedEmail VerifiedEmail { get; set; }
+
+ [JsonProperty("verified-primary-email")]
+ public VerifiedPrimaryEmail VerifiedPrimaryEmail { get; set; }
+
+ [JsonProperty("visibility")]
+ public object Visibility { get; set; }
+ }
+
+ public class GivenNames
+ {
+
+ [JsonProperty("value")]
+ public string Value { get; set; }
+
+ [JsonProperty("visibility")]
+ public object Visibility { get; set; }
+ }
+
+ public class FamilyName
+ {
+
+ [JsonProperty("value")]
+ public string Value { get; set; }
+
+ [JsonProperty("visibility")]
+ public object Visibility { get; set; }
+ }
+
+ public class OtherNames
+ {
+
+ [JsonProperty("other-name")]
+ public object[] OtherName { get; set; }
+
+ [JsonProperty("visibility")]
+ public string Visibility { get; set; }
+ }
+
+ public class PersonalDetails
+ {
+
+ [JsonProperty("given-names")]
+ public GivenNames GivenNames { get; set; }
+
+ [JsonProperty("family-name")]
+ public FamilyName FamilyName { get; set; }
+
+ [JsonProperty("credit-name")]
+ public object CreditName { get; set; }
+
+ [JsonProperty("other-names")]
+ public OtherNames OtherNames { get; set; }
+ }
+
+ public class Biography
+ {
+
+ [JsonProperty("value")]
+ public object Value { get; set; }
+
+ [JsonProperty("visibility")]
+ public string Visibility { get; set; }
+ }
+
+ public class ResearcherUrls
+ {
+
+ [JsonProperty("researcher-url")]
+ public object[] ResearcherUrl { get; set; }
+
+ [JsonProperty("visibility")]
+ public string Visibility { get; set; }
+ }
+
+ public class Email
+ {
+
+ [JsonProperty("value")]
+ public string Value { get; set; }
+
+ [JsonProperty("primary")]
+ public bool Primary { get; set; }
+
+ [JsonProperty("current")]
+ public bool Current { get; set; }
+
+ [JsonProperty("verified")]
+ public bool Verified { get; set; }
+
+ [JsonProperty("visibility")]
+ public string Visibility { get; set; }
+
+ [JsonProperty("source")]
+ public string Source { get; set; }
+
+ [JsonProperty("source-client-id")]
+ public object SourceClientId { get; set; }
+ }
+
+ public class ContactDetails
+ {
+
+ [JsonProperty("email")]
+ public Email[] Email { get; set; }
+
+ [JsonProperty("address")]
+ public object Address { get; set; }
+ }
+
+ public class ExternalIdentifiers
+ {
+
+ [JsonProperty("external-identifier")]
+ public object[] ExternalIdentifier { get; set; }
+
+ [JsonProperty("visibility")]
+ public string Visibility { get; set; }
+ }
+
+ public class OrcidBio
+ {
+
+ [JsonProperty("personal-details")]
+ public PersonalDetails PersonalDetails { get; set; }
+
+ [JsonProperty("biography")]
+ public Biography Biography { get; set; }
+
+ [JsonProperty("researcher-urls")]
+ public ResearcherUrls ResearcherUrls { get; set; }
+
+ [JsonProperty("contact-details")]
+ public ContactDetails ContactDetails { get; set; }
+
+ [JsonProperty("keywords")]
+ public object Keywords { get; set; }
+
+ [JsonProperty("external-identifiers")]
+ public ExternalIdentifiers ExternalIdentifiers { get; set; }
+
+ [JsonProperty("delegation")]
+ public object Delegation { get; set; }
+
+ [JsonProperty("scope")]
+ public object Scope { get; set; }
+ }
+
+ public class OrcidProfile
+ {
+
+ [JsonProperty("orcid")]
+ public object Orcid { get; set; }
+
+ [JsonProperty("orcid-id")]
+ public object OrcidId { get; set; }
+
+ [JsonProperty("orcid-identifier")]
+ public OrcidIdentifier OrcidIdentifier { get; set; }
+
+ [JsonProperty("orcid-deprecated")]
+ public object OrcidDeprecated { get; set; }
+
+ [JsonProperty("orcid-preferences")]
+ public OrcidPreferences OrcidPreferences { get; set; }
+
+ [JsonProperty("orcid-history")]
+ public OrcidHistory OrcidHistory { get; set; }
+
+ [JsonProperty("orcid-bio")]
+ public OrcidBio OrcidBio { get; set; }
+
+ [JsonProperty("orcid-activities")]
+ public object OrcidActivities { get; set; }
+
+ [JsonProperty("orcid-internal")]
+ public object OrcidInternal { get; set; }
+
+ [JsonProperty("type")]
+ public string Type { get; set; }
+
+ [JsonProperty("group-type")]
+ public object GroupType { get; set; }
+
+ [JsonProperty("client-type")]
+ public object ClientType { get; set; }
+ }
+
+ public class OrcidProfileMessage
+ {
+
+ [JsonProperty("message-version")]
+ public string MessageVersion { get; set; }
+
+ [JsonProperty("orcid-profile")]
+ public OrcidProfile OrcidProfile { get; set; }
+
+ [JsonProperty("error-desc")]
+ public object ErrorDesc { get; set; }
+ }
+}
diff --git a/src/Owin.Security.Providers.Orcid/Message/OrcidMessageExtensions.cs b/src/Owin.Security.Providers.Orcid/Message/OrcidMessageExtensions.cs
new file mode 100644
index 0000000..467a539
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/Message/OrcidMessageExtensions.cs
@@ -0,0 +1,35 @@
+using Microsoft.Owin;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Owin.Security.Providers.Orcid.Message
+{
+ public static class OrcidMessageExtensions
+ {
+ public static OrcidAuthenticatedContext ToAuthenticationContext(this string json, IOwinContext context, string orcid, string accessToken)
+ {
+ var profile = JsonConvert.DeserializeObject(json);
+
+ var user = JObject.Parse(json);
+
+ var authenticatedContext = new OrcidAuthenticatedContext(context, user, accessToken);
+
+ var email = profile.OrcidProfile.OrcidBio?.ContactDetails?.Email?.LastOrDefault();
+ if(email != null)
+ authenticatedContext.Email = email.Value;
+
+ authenticatedContext.Id = orcid;
+ authenticatedContext.UserName = orcid;
+
+ authenticatedContext.FirstName = profile.OrcidProfile.OrcidBio.PersonalDetails.GivenNames.Value;
+ authenticatedContext.LastName = profile.OrcidProfile.OrcidBio.PersonalDetails.FamilyName.Value;
+
+ return authenticatedContext;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Owin.Security.Providers.Orcid/OrcidAuthenticationEndpoints.cs b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationEndpoints.cs
new file mode 100644
index 0000000..bf878b9
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationEndpoints.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using Microsoft.Owin;
+using Microsoft.Owin.Security;
+
+namespace Owin.Security.Providers.Orcid
+{
+ public class OrcidAuthenticationEndpoints
+ {
+ public static class Default
+ {
+ public const string AuthorizationEndPoint = @"https://orcid.org/oauth/authorize";
+ public const string TokenEndpoint = @"https://pub.orcid.org/oauth/token";
+ public const string ApiEndpoint = @"http://pub.orcid.org/v1.2";
+ }
+
+ ///
+ /// Endpoint which is used to redirect users to request Orcid access
+ ///
+ public string AuthorizationEndpoint { get; set; }
+
+ ///
+ /// Endpoint which is used to exchange code for access token
+ ///
+ public string TokenEndpoint { get; set; }
+
+ ///
+ /// Endpoint which is used to exchange code for access token
+ ///
+ public string ApiEndpoint { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Owin.Security.Providers.Orcid/OrcidAuthenticationExtensions.cs b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationExtensions.cs
new file mode 100644
index 0000000..c0ecfed
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Owin.Security.Providers.Orcid
+{
+ public static class OrcidAuthenticationExtensions
+ {
+ public static IAppBuilder UseOrcidAuthentication(this IAppBuilder app,
+ OrcidAuthenticationOptions options)
+ {
+ if (app == null)
+ throw new ArgumentNullException(nameof(app));
+ if (options == null)
+ throw new ArgumentNullException(nameof(options));
+
+ app.Use(typeof(OrcidAuthenticationMiddleware), app, options);
+
+ return app;
+ }
+
+ public static IAppBuilder UseOrcidAuthentication(this IAppBuilder app, string clientId, string clientSecret)
+ {
+ return app.UseOrcidAuthentication(new OrcidAuthenticationOptions
+ {
+ ClientId = clientId,
+ ClientSecret = clientSecret
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Owin.Security.Providers.Orcid/OrcidAuthenticationHandler.cs b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationHandler.cs
new file mode 100644
index 0000000..a01e5e3
--- /dev/null
+++ b/src/Owin.Security.Providers.Orcid/OrcidAuthenticationHandler.cs
@@ -0,0 +1,275 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using System.Web;
+using Microsoft.Owin;
+using Microsoft.Owin.Infrastructure;
+using Microsoft.Owin.Logging;
+using Microsoft.Owin.Security;
+using Microsoft.Owin.Security.Infrastructure;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Owin.Security.Providers.Orcid.Message;
+
+namespace Owin.Security.Providers.Orcid
+{
+ public class OrcidAuthenticationHandler : AuthenticationHandler
+ {
+ private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
+
+ private readonly ILogger _logger;
+ private readonly HttpClient _httpClient;
+
+ public OrcidAuthenticationHandler(HttpClient httpClient, ILogger logger)
+ {
+ this._httpClient = httpClient;
+ this._logger = logger;
+ }
+
+ protected override async Task AuthenticateCoreAsync()
+ {
+ AuthenticationProperties properties = new AuthenticationProperties();
+
+ try
+ {
+ string code = null;
+ string state = null;
+
+ IReadableStringCollection query = Request.Query;
+ IList values = query.GetValues("code");
+ if (values != null && values.Count == 1)
+ {
+ code = values[0];
+ }
+ values = query.GetValues("state");
+ if (values != null && values.Count == 1)
+ {
+ state = values[0];
+ }
+
+ if (state != null)
+ {
+ properties = Options.StateDataFormat.Unprotect(state);
+ if (properties == null)
+ {
+ return null;
+ }
+
+ // OAuth2 10.12 CSRF
+ if (!ValidateCorrelationId(properties, _logger))
+ {
+ return new AuthenticationTicket(null, properties);
+ }
+ }
+
+ string requestPrefix = Request.Scheme + "://" + Request.Host;
+ string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath;
+
+ // Build up the body for the token request
+ var body = new List>
+ {
+ new KeyValuePair("client_id", Options.ClientId),
+ new KeyValuePair("client_secret", Options.ClientSecret),
+ new KeyValuePair("scope", "/read-public"),
+ new KeyValuePair("grant_type", "authorization_code"),
+ new KeyValuePair("code", code),
+ new KeyValuePair("redirect_uri", redirectUri),
+ };
+
+ // Request the token
+ var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.Endpoints.TokenEndpoint);
+ requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ requestMessage.Content = new FormUrlEncodedContent(body);
+
+ HttpResponseMessage tokenResponse = await _httpClient.SendAsync(requestMessage);
+ tokenResponse.EnsureSuccessStatusCode();
+ string text = await tokenResponse.Content.ReadAsStringAsync();
+
+ // Deserializes the token response
+ dynamic response = JsonConvert.DeserializeObject(text);
+ string accessToken = (string)response.access_token;
+ string refreshToken = (string)response.refresh_token;
+ string orcid = (string)response.orcid;
+
+ string profileEndpoint =
+ string.Format("{0}/{1}/{2}",
+ Options.Endpoints.ApiEndpoint,
+ orcid,
+ "orcid-profile/");
+
+ // Get Orcid profile
+ HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, profileEndpoint);
+
+ //Requesting public info for now - no authirization needed
+ //userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
+
+ userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+
+ HttpResponseMessage userResponse = await _httpClient.SendAsync(userRequest, Request.CallCancelled);
+ userResponse.EnsureSuccessStatusCode();
+ text = await userResponse.Content.ReadAsStringAsync();
+
+ // Get the Orcid user using the user info endpoint, which is part of the token - response.id
+ var context = text.ToAuthenticationContext(Context, orcid, accessToken);
+
+ context.Identity = new ClaimsIdentity(
+ Options.AuthenticationType,
+ ClaimsIdentity.DefaultNameClaimType,
+ ClaimsIdentity.DefaultRoleClaimType);
+
+ if (!string.IsNullOrEmpty(context.Id))
+ {
+ context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType));
+ }
+
+ if (!string.IsNullOrEmpty(context.UserName))
+ {
+ context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, XmlSchemaString, Options.AuthenticationType));
+ }
+
+ if (!string.IsNullOrEmpty(context.Email))
+ {
+ context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType));
+ }
+
+ if (!string.IsNullOrEmpty(context.FirstName))
+ {
+ context.Identity.AddClaim(new Claim(ClaimTypes.GivenName, context.FirstName, XmlSchemaString, Options.AuthenticationType));
+ }
+
+ if (!string.IsNullOrEmpty(context.LastName))
+ {
+ context.Identity.AddClaim(new Claim(ClaimTypes.Surname, context.LastName, XmlSchemaString, Options.AuthenticationType));
+ }
+
+ context.Properties = properties;
+
+ await Options.Provider.Authenticated(context);
+
+ return new AuthenticationTicket(context.Identity, context.Properties);
+ }
+ catch (Exception ex)
+ {
+ _logger.WriteError(ex.Message);
+ }
+ return new AuthenticationTicket(null, properties);
+ }
+
+ protected override Task ApplyResponseChallengeAsync()
+ {
+ if (Response.StatusCode != 401)
+ {
+ return Task.FromResult