From 894c018152536db81bc8f0089cd67072e7353d0c Mon Sep 17 00:00:00 2001 From: Victor Antofica Date: Wed, 17 Jun 2015 15:59:08 +0100 Subject: [PATCH] add Stripe provider and fix build --- AngJobs/AngJobs.csproj | 2 +- AngJobs/Web.config | 2 +- .../Asana/AsanaAuthenticationExtensions.cs | 29 -- .../Asana/AsanaAuthenticationHandler.cs | 247 ------------ .../Asana/AsanaAuthenticationMiddleware.cs | 87 ----- .../Asana/AsanaAuthenticationOptions.cs | 136 ------- Owin.Security.Providers/Asana/Constants.cs | 7 - .../Provider/AsanaAuthenticatedContext.cs | 90 ----- .../Provider/AsanaAuthenticationProvider.cs | 50 --- .../Provider/AsanaReturnEndpointContext.cs | 26 -- .../Provider/IAsanaAuthenticationProvider.cs | 24 -- .../BattleNetAuthenticationExtensions.cs | 29 -- .../BattleNetAuthenticationHandler.cs | 293 -------------- .../BattleNetAuthenticationMiddleware.cs | 84 ---- .../BattleNetAuthenticationOptions.cs | 118 ------ .../BattleNet/Constants.cs | 8 - .../Provider/BattleNetAuthenticatedContext.cs | 97 ----- .../BattleNetAuthenticationProvider.cs | 51 --- .../BattleNetReturnEndpointContext.cs | 26 -- .../IBattleNetAuthenticationProvider.cs | 21 - .../DeviantArt/Constants.cs | 7 - .../DeviantAuthenticationExtensions.cs | 42 -- .../DeviantAuthenticationHandler.cs | 235 ----------- .../DeviantAuthenticationMiddleware.cs | 89 ----- .../DeviantAuthenticationOptions.cs | 150 ------- .../Provider/DeviantAuthenticatedContext.cs | 79 ---- .../Provider/DeviantAuthenticationProvider.cs | 51 --- .../Provider/DeviantReturnEndpointContext.cs | 26 -- .../IDeviantAuthenticationProvider.cs | 24 -- Owin.Security.Providers/Dropbox/Constants.cs | 7 - .../DropboxAuthenticationExtensions.cs | 29 -- .../Dropbox/DropboxAuthenticationHandler.cs | 229 ----------- .../DropboxAuthenticationMiddleware.cs | 85 ---- .../Dropbox/DropboxAuthenticationOptions.cs | 92 ----- .../Provider/DropboxAuthenticatedContext.cs | 73 ---- .../Provider/DropboxAuthenticationProvider.cs | 50 --- .../Provider/DropboxReturnEndpointContext.cs | 26 -- .../IDropboxAuthenticationProvider.cs | 24 -- .../EVEOnline/Constants.cs | 7 - .../EVEOnlineAuthenticationExtensions.cs | 27 -- .../EVEOnlineAuthenticationHandler.cs | 284 -------------- .../EVEOnlineAuthenticationMiddleware.cs | 84 ---- .../EVEOnlineAuthenticationOptions.cs | 113 ------ .../Provider/EVEOnlineAuthenticatedContext.cs | 99 ----- .../EVEOnlineAuthenticationProvider.cs | 51 --- .../EVEOnlineReturnEndpointContext.cs | 26 -- .../IEVEOnlineAuthenticationProvider.cs | 21 - Owin.Security.Providers/Flickr/Constants.cs | 7 - .../Flickr/FlickrAuthenticationExtensions.cs | 29 -- .../Flickr/FlickrAuthenticationHandler.cs | 367 ------------------ .../Flickr/FlickrAuthenticationMiddleware.cs | 90 ----- .../Flickr/FlickrAuthenticationOptions.cs | 99 ----- .../Flickr/Messages/AccessToken.cs | 25 -- .../Flickr/Messages/RequestToken.cs | 29 -- .../Flickr/Messages/RequestTokenSerializer.cs | 106 ----- .../Flickr/Messages/Serializers.cs | 22 -- .../Provider/FlickrAuthenticatedContext.cs | 66 ---- .../Provider/FlickrAuthenticationProvider.cs | 45 --- .../Provider/FlickrReturnEndpointContext.cs | 21 - .../Provider/IFlickrAuthenticationProvider.cs | 26 -- .../Foursquare/Constants.cs | 7 - .../FoursquareAuthenticationExtensions.cs | 31 -- .../FoursquareAuthenticationHandler.cs | 241 ------------ .../FoursquareAuthenticationMiddleware.cs | 89 ----- .../FoursquareAuthenticationOptions.cs | 93 ----- .../FoursquareAuthenticatedContext.cs | 167 -------- .../FoursquareAuthenticationProvider.cs | 50 --- .../FoursquareReturnEndpointContext.cs | 22 -- .../IFoursquareAuthenticationProvider.cs | 24 -- .../GitHub/GitHubAuthenticationHandler.cs | 4 - .../Provider/GitHubAuthenticatedContext.cs | 6 - .../HealthGraph/Constants.cs | 7 - .../HealthGraphAuthenticationExtensions.cs | 33 -- .../HealthGraphAuthenticationHandler.cs | 234 ----------- .../HealthGraphAuthenticationMiddleware.cs | 83 ---- .../HealthGraphAuthenticationOptions.cs | 96 ----- .../HealthGraphAuthenticatedContext.cs | 44 --- .../HealthGraphAuthenticationProvider.cs | 28 -- .../HealthGraphReturnEndpointContext.cs | 15 - .../IHealthGraphAuthenticationProvider.cs | 12 - .../InstagramAuthenticationHandler.cs | 6 +- .../LinkedIn/LinkedInAuthenticationHandler.cs | 8 +- .../LinkedInAuthenticationMiddleware.cs | 3 - .../Owin.Security.Providers.csproj | 169 +------- ...Owin.Security.Providers.csproj.DotSettings | 6 +- Owin.Security.Providers/PayPal/Constants.cs | 7 - .../PayPal/PayPalAuthenticationExtensions.cs | 29 -- .../PayPal/PayPalAuthenticationHandler.cs | 238 ------------ .../PayPal/PayPalAuthenticationMiddleware.cs | 87 ----- .../PayPal/PayPalAuthenticationOptions.cs | 154 -------- .../Provider/IPayPalAuthenticationProvider.cs | 24 -- .../Provider/PayPalAuthenticatedContext.cs | 84 ---- .../Provider/PayPalAuthenticationProvider.cs | 50 --- .../Provider/PayPalReturnEndpointContext.cs | 26 -- .../Properties/AssemblyInfo.cs | 6 +- .../SalesforceAuthenticatedContext.cs | 9 +- .../SalesforceAuthenticationHandler.cs | 10 +- .../SoundCloud/Constants.cs | 7 - .../ISoundCloudAuthenticationProvider.cs | 29 -- .../SoundCloudAuthenticatedContext.cs | 64 --- .../SoundCloudAuthenticationProvider.cs | 54 --- .../SoundCloudReturnEndpointContext.cs | 21 - .../SoundCloudAuthenticationExtensions.cs | 29 -- .../SoundCloudAuthenticationHandler.cs | 238 ------------ .../SoundCloudAuthenticationMiddleware.cs | 81 ---- .../SoundCloudAuthenticationOptions.cs | 93 ----- Owin.Security.Providers/Spotify/Constants.cs | 7 - .../ISpotifyAuthenticationProvider.cs | 24 -- .../Provider/SpotifyAuthenticatedContext.cs | 99 ----- .../Provider/SpotifyAuthenticationProvider.cs | 50 --- .../SpotifyAuthenticationExtensions.cs | 29 -- .../Spotify/SpotifyAuthenticationHandler.cs | 243 ------------ .../SpotifyAuthenticationMiddleware.cs | 86 ---- .../Spotify/SpotifyAuthenticationOptions.cs | 100 ----- .../Steam/SteamAuthenticationExtensions.cs | 10 +- .../Steam/SteamAuthenticationOptions.cs | 11 +- Owin.Security.Providers/Stripe/Constants.cs | 13 + .../IStripeAuthenticationProvider.cs} | 16 +- .../Provider/StripeAuthenticatedContext.cs} | 79 ++-- .../Provider/StripeAuthenticationProvider.cs} | 28 +- .../Provider/StripeReturnEndpointContext.cs} | 15 +- .../Stripe/StripeAuthenticationExtensions.cs | 33 ++ .../StripeAuthenticationHandler.cs} | 89 +++-- .../StripeAuthenticationMiddleware.cs} | 38 +- .../StripeAuthenticationOptions.cs} | 43 +- Owin.Security.Providers/Twitch/Constants.cs | 7 - .../Provider/ITwitchAuthenticationProvider.cs | 24 -- .../Provider/TwitchReturnEndpointContext.cs | 26 -- .../Twitch/TwitchAuthenticationExtensions.cs | 41 -- .../Twitch/TwitchAuthenticationHandler.cs | 241 ------------ .../Twitch/TwitchAuthenticationMiddleware.cs | 87 ----- .../Twitch/TwitchAuthenticationOptions.cs | 145 ------- .../Untappd/ApiResponse.cs | 26 -- Owin.Security.Providers/Untappd/Constants.cs | 7 - .../IUntappdAuthenticationProvider.cs | 24 -- .../Provider/UntappdAuthenticatedContext.cs | 95 ----- .../Provider/UntappdAuthenticationProvider.cs | 50 --- .../Provider/UntappdReturnEndpointContext.cs | 26 -- .../UntappdAuthenticationExtensions.cs | 41 -- .../Untappd/UntappdAuthenticationHandler.cs | 252 ------------ .../UntappdAuthenticationMiddleware.cs | 85 ---- .../Untappd/UntappdAuthenticationOptions.cs | 143 ------- .../VisualStudio/Constants.cs | 11 - .../IVisualStudioAuthenticationProvider.cs | 23 -- .../VisualStudioAuthenticatedContext.cs | 94 ----- .../VisualStudioAuthenticationProvider.cs | 47 --- .../VisualStudioReturnEndpointContext.cs | 23 -- .../VisualStudioAuthenticationExtensions.cs | 21 - .../VisualStudioAuthenticationHandler.cs | 211 ---------- .../VisualStudioAuthenticationMiddleware.cs | 80 ---- .../VisualStudioAuthenticationOptions.cs | 141 ------- .../Wargaming/Constants.cs | 18 - ...argamingAccountAuthenticationExtensions.cs | 69 ---- .../WargamingAuthenticationHandler.cs | 36 -- .../WargamingAuthenticationMiddleware.cs | 35 -- .../WargamingAuthenticationOptions.cs | 32 -- .../WordPress/Constants.cs | 7 - .../IWordPressAuthenticationProvider.cs | 24 -- .../Provider/WordPressAuthenticatedContext.cs | 112 ------ .../WordPressAuthenticationProvider.cs | 50 --- .../WordPressReturnEndpointContext.cs | 26 -- .../WordPressAuthenticationExtensions.cs | 29 -- .../WordPressAuthenticationMiddleware.cs | 85 ---- .../WordPressAuthenticationOptions.cs | 92 ----- Owin.Security.Providers/Yammer/Constants.cs | 8 - .../Provider/YammerAuthenticatedContext.cs | 87 ----- .../Provider/YammerAuthenticationProvider.cs | 50 --- .../Provider/YammerReturnEndpointContext.cs | 24 -- .../Yammer/YammerAuthenticationExtensions.cs | 28 -- .../Yammer/YammerAuthenticationHandler.cs | 250 ------------ 170 files changed, 256 insertions(+), 10997 deletions(-) delete mode 100644 Owin.Security.Providers/Asana/AsanaAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Asana/AsanaAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Asana/AsanaAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Asana/AsanaAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Asana/Constants.cs delete mode 100644 Owin.Security.Providers/Asana/Provider/AsanaAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Asana/Provider/AsanaAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Asana/Provider/AsanaReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Asana/Provider/IAsanaAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/BattleNet/BattleNetAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/BattleNet/BattleNetAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/BattleNet/BattleNetAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/BattleNet/BattleNetAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/BattleNet/Constants.cs delete mode 100644 Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/BattleNet/Provider/BattleNetReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/BattleNet/Provider/IBattleNetAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/DeviantArt/Constants.cs delete mode 100644 Owin.Security.Providers/DeviantArt/DeviantAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/DeviantArt/DeviantAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/DeviantArt/DeviantAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/DeviantArt/DeviantAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/DeviantArt/Provider/DeviantReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/DeviantArt/Provider/IDeviantAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Dropbox/Constants.cs delete mode 100644 Owin.Security.Providers/Dropbox/DropboxAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Dropbox/DropboxAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Dropbox/DropboxAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Dropbox/DropboxAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Dropbox/Provider/DropboxReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Dropbox/Provider/IDropboxAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/EVEOnline/Constants.cs delete mode 100644 Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/EVEOnline/Provider/EVEOnlineReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/EVEOnline/Provider/IEVEOnlineAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Flickr/Constants.cs delete mode 100644 Owin.Security.Providers/Flickr/FlickrAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Flickr/FlickrAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Flickr/FlickrAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Flickr/FlickrAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Flickr/Messages/AccessToken.cs delete mode 100644 Owin.Security.Providers/Flickr/Messages/RequestToken.cs delete mode 100644 Owin.Security.Providers/Flickr/Messages/RequestTokenSerializer.cs delete mode 100644 Owin.Security.Providers/Flickr/Messages/Serializers.cs delete mode 100644 Owin.Security.Providers/Flickr/Provider/FlickrAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Flickr/Provider/FlickrAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Flickr/Provider/FlickrReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Flickr/Provider/IFlickrAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Foursquare/Constants.cs delete mode 100644 Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Foursquare/Provider/FoursquareReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Foursquare/Provider/IFoursquareAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/HealthGraph/Constants.cs delete mode 100644 Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/HealthGraph/Provider/HealthGraphReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/HealthGraph/Provider/IHealthGraphAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/PayPal/Constants.cs delete mode 100644 Owin.Security.Providers/PayPal/PayPalAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/PayPal/PayPalAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/PayPal/PayPalAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/PayPal/PayPalAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/PayPal/Provider/IPayPalAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/PayPal/Provider/PayPalAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/PayPal/Provider/PayPalAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/PayPal/Provider/PayPalReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/SoundCloud/Constants.cs delete mode 100644 Owin.Security.Providers/SoundCloud/Provider/ISoundCloudAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/SoundCloud/Provider/SoundCloudReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Spotify/Constants.cs delete mode 100644 Owin.Security.Providers/Spotify/Provider/ISpotifyAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Spotify/SpotifyAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Spotify/SpotifyAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Spotify/SpotifyAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Spotify/SpotifyAuthenticationOptions.cs create mode 100644 Owin.Security.Providers/Stripe/Constants.cs rename Owin.Security.Providers/{Yammer/Provider/IYammerAuthenticationProvider.cs => Stripe/Provider/IStripeAuthenticationProvider.cs} (62%) rename Owin.Security.Providers/{Twitch/Provider/TwitchAuthenticatedContext.cs => Stripe/Provider/StripeAuthenticatedContext.cs} (50%) rename Owin.Security.Providers/{Twitch/Provider/TwitchAuthenticationProvider.cs => Stripe/Provider/StripeAuthenticationProvider.cs} (66%) rename Owin.Security.Providers/{Spotify/Provider/SpotifyReturnEndpointContext.cs => Stripe/Provider/StripeReturnEndpointContext.cs} (57%) create mode 100644 Owin.Security.Providers/Stripe/StripeAuthenticationExtensions.cs rename Owin.Security.Providers/{WordPress/WordPressAuthenticationHandler.cs => Stripe/StripeAuthenticationHandler.cs} (73%) rename Owin.Security.Providers/{Yammer/YammerAuthenticationMiddleware.cs => Stripe/StripeAuthenticationMiddleware.cs} (62%) rename Owin.Security.Providers/{Yammer/YammerAuthenticationOptions.cs => Stripe/StripeAuthenticationOptions.cs} (75%) delete mode 100644 Owin.Security.Providers/Twitch/Constants.cs delete mode 100644 Owin.Security.Providers/Twitch/Provider/ITwitchAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Twitch/Provider/TwitchReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Twitch/TwitchAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Twitch/TwitchAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Twitch/TwitchAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Twitch/TwitchAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Untappd/ApiResponse.cs delete mode 100644 Owin.Security.Providers/Untappd/Constants.cs delete mode 100644 Owin.Security.Providers/Untappd/Provider/IUntappdAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Untappd/Provider/UntappdAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Untappd/Provider/UntappdAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Untappd/Provider/UntappdReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Untappd/UntappdAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Untappd/UntappdAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Untappd/UntappdAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Untappd/UntappdAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/VisualStudio/Constants.cs delete mode 100644 Owin.Security.Providers/VisualStudio/Provider/IVisualStudioAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/VisualStudio/Provider/VisualStudioReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Wargaming/Constants.cs delete mode 100644 Owin.Security.Providers/Wargaming/WargamingAccountAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Wargaming/WargamingAuthenticationHandler.cs delete mode 100644 Owin.Security.Providers/Wargaming/WargamingAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/Wargaming/WargamingAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/WordPress/Constants.cs delete mode 100644 Owin.Security.Providers/WordPress/Provider/IWordPressAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/WordPress/Provider/WordPressAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/WordPress/Provider/WordPressAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/WordPress/Provider/WordPressReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/WordPress/WordPressAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/WordPress/WordPressAuthenticationMiddleware.cs delete mode 100644 Owin.Security.Providers/WordPress/WordPressAuthenticationOptions.cs delete mode 100644 Owin.Security.Providers/Yammer/Constants.cs delete mode 100644 Owin.Security.Providers/Yammer/Provider/YammerAuthenticatedContext.cs delete mode 100644 Owin.Security.Providers/Yammer/Provider/YammerAuthenticationProvider.cs delete mode 100644 Owin.Security.Providers/Yammer/Provider/YammerReturnEndpointContext.cs delete mode 100644 Owin.Security.Providers/Yammer/YammerAuthenticationExtensions.cs delete mode 100644 Owin.Security.Providers/Yammer/YammerAuthenticationHandler.cs diff --git a/AngJobs/AngJobs.csproj b/AngJobs/AngJobs.csproj index d86fa8e..682cffd 100644 --- a/AngJobs/AngJobs.csproj +++ b/AngJobs/AngJobs.csproj @@ -718,7 +718,7 @@ - + {6ad9ba00-1330-426d-8bae-2d3bc0d976e4} Owin.Security.Providers diff --git a/AngJobs/Web.config b/AngJobs/Web.config index cea8899..df4a6f2 100644 --- a/AngJobs/Web.config +++ b/AngJobs/Web.config @@ -4,7 +4,7 @@
- + diff --git a/Owin.Security.Providers/Asana/AsanaAuthenticationExtensions.cs b/Owin.Security.Providers/Asana/AsanaAuthenticationExtensions.cs deleted file mode 100644 index bbb8dbd..0000000 --- a/Owin.Security.Providers/Asana/AsanaAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Asana -{ - public static class AsanaAuthenticationExtensions - { - public static IAppBuilder UseAsanaAuthentication(this IAppBuilder app, - AsanaAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(AsanaAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseAsanaAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseAsanaAuthentication(new AsanaAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/AsanaAuthenticationHandler.cs b/Owin.Security.Providers/Asana/AsanaAuthenticationHandler.cs deleted file mode 100644 index 04d8b9c..0000000 --- a/Owin.Security.Providers/Asana/AsanaAuthenticationHandler.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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; - -namespace Owin.Security.Providers.Asana -{ - public class AsanaAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public AsanaAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - 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]; - } - - 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>(); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("code", code)); - - /*Your app makes a POST request to https://app.asana.com/-/oauth_token, passing the parameters as part of a standard form-encoded post body. - grant_type - required Must be authorization_code - client_id - required The Client ID uniquely identifies the application making the request. - client_secret - required The Client Secret belonging to the app, found in the details pane of the developer view - redirect_uri - required Must match the redirect_uri specified in the original request - code - required The code you are exchanging for an auth token - */ - - // 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; - - /* - * In the response, you will receive a JSON payload with the following parameters: - access_token - The token to use in future requests against the API - expires_in - The number of seconds the token is valid, typically 3600 (one hour) - token_type - The type of token, in our case, bearer - refresh_token - If exchanging a code, a long-lived token that can be used to get new access tokens when old ones expire. - data - A JSON object encoding a few key fields about the logged-in user, currently id, name, and email. - */ - - // Get the Asana user - - var context = new AsanaAuthenticatedContext(Context, response.data, 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.Email)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim("urn:asana:name", context.Name, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - string state = Options.StateDataFormat.Protect(properties); - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&state=" + Uri.EscapeDataString(state) - ; - - - /*Your app redirects the user to https://app.asana.com/-/oauth_authorize, passing parameters along as a standard query string: - - client_id - required The Client ID uniquely identifies the application making the request. - redirect_uri - required The URI to redirect to on success or error. This must match the Redirect URL specified in the application settings. - response_type - required Must be one of either code (if using the Authorization Code Grant flow) or token (if using the Implicit Grant flow). Other flows are currently not supported. - state - optional Encodes state of the app, which will be returned verbatim in the response and can be used to match the response up to a given request. - */ - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new AsanaReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/AsanaAuthenticationMiddleware.cs b/Owin.Security.Providers/Asana/AsanaAuthenticationMiddleware.cs deleted file mode 100644 index 8e7a95e..0000000 --- a/Owin.Security.Providers/Asana/AsanaAuthenticationMiddleware.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.Asana -{ - public class AsanaAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public AsanaAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - AsanaAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new AsanaAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (AsanaAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin Asana middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new AsanaAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(AsanaAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/AsanaAuthenticationOptions.cs b/Owin.Security.Providers/Asana/AsanaAuthenticationOptions.cs deleted file mode 100644 index 92ea3a6..0000000 --- a/Owin.Security.Providers/Asana/AsanaAuthenticationOptions.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.Asana -{ - public class AsanaAuthenticationOptions : AuthenticationOptions - { - public class AsanaAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request Asana access - /// - /// - /// Defaults to https://app.asana.com/-/oauth_authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://app.asana.com/-/oauth_token - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://asana.com/1/OAuthGetRequestToken - /// - public string UserInfoEndpoint { get; set; } - } - - private const string AuthorizationEndPoint = "https://app.asana.com/-/oauth_authorize"; - private const string TokenEndpoint = "https://app.asana.com/-/oauth_token"; - - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Asana. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Asana. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Asana. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-asana". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Asana supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Asana supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against Asana. Overriding these endpoints allows you to use Asana Enterprise for - /// authentication. - /// - public AsanaAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IAsanaAuthenticationProvider Provider { get; set; } - - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public AsanaAuthenticationOptions() - : base("Asana") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-asana"); - AuthenticationMode = AuthenticationMode.Passive; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new AsanaAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint - }; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/Constants.cs b/Owin.Security.Providers/Asana/Constants.cs deleted file mode 100644 index 7a00a4f..0000000 --- a/Owin.Security.Providers/Asana/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Asana -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Asana"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/Provider/AsanaAuthenticatedContext.cs b/Owin.Security.Providers/Asana/Provider/AsanaAuthenticatedContext.cs deleted file mode 100644 index c2a1a90..0000000 --- a/Owin.Security.Providers/Asana/Provider/AsanaAuthenticatedContext.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Asana -{ - /// - /// Contains information about the login session as well as the user . - /// - public class AsanaAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Asana Access token - public AsanaAuthenticatedContext(IOwinContext context, dynamic user, string accessToken) - : base(context) - { - User = user; - AccessToken = accessToken; - - Id = TryGetValue(user, "id"); - Name = TryGetValue(user, "name"); - Email = TryGetValue(user, "email"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Asana user obtained from the User Info endpoint. By default this is https://asana.com/1/OAuthGetRequestToken but it can be - /// overridden in the options - /// - public JObject User { get; private set; } - - /// - /// Gets the Asana access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Asana user ID - /// - public string Id { get; private set; } - - /// - /// Gets the user's name - /// - public string Name { get; private set; } - - /// - /// Gets the Asana email - /// - public string Email { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(dynamic user, string propertyName) - { - string value = null; - - try - { - value = (string)user[propertyName]; - } - catch - { - - } - - return value; - } - } -} diff --git a/Owin.Security.Providers/Asana/Provider/AsanaAuthenticationProvider.cs b/Owin.Security.Providers/Asana/Provider/AsanaAuthenticationProvider.cs deleted file mode 100644 index b0f2a3c..0000000 --- a/Owin.Security.Providers/Asana/Provider/AsanaAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Asana -{ - /// - /// Default implementation. - /// - public class AsanaAuthenticationProvider : IAsanaAuthenticationProvider - { - /// - /// Initializes a - /// - public AsanaAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Asana succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(AsanaAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(AsanaReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Asana/Provider/AsanaReturnEndpointContext.cs b/Owin.Security.Providers/Asana/Provider/AsanaReturnEndpointContext.cs deleted file mode 100644 index 19d0f29..0000000 --- a/Owin.Security.Providers/Asana/Provider/AsanaReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Asana -{ - /// - /// Provides context information to middleware providers. - /// - public class AsanaReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public AsanaReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Asana/Provider/IAsanaAuthenticationProvider.cs b/Owin.Security.Providers/Asana/Provider/IAsanaAuthenticationProvider.cs deleted file mode 100644 index 418f121..0000000 --- a/Owin.Security.Providers/Asana/Provider/IAsanaAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Asana -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IAsanaAuthenticationProvider - { - /// - /// Invoked whenever Asana succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(AsanaAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(AsanaReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationExtensions.cs b/Owin.Security.Providers/BattleNet/BattleNetAuthenticationExtensions.cs deleted file mode 100644 index 64ad5ea..0000000 --- a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.BattleNet -{ - public static class BattleNetAuthenticationExtensions - { - - public static IAppBuilder UseBattleNetAuthentication(this IAppBuilder app, BattleNetAuthenticationOptions options) - { - if (app == null) - throw new ArgumentException("app"); - if (options == null) - throw new ArgumentException("options"); - - app.Use(typeof(BattleNetAuthenticationMiddleware), app, options); - - return app; - } - public static IAppBuilder UseBattleNetAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseBattleNetAuthentication(new BattleNetAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret, - Region = Region.US - }); - } - } -} diff --git a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationHandler.cs b/Owin.Security.Providers/BattleNet/BattleNetAuthenticationHandler.cs deleted file mode 100644 index 8a8454a..0000000 --- a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationHandler.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.Owin.Infrastructure; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Infrastructure; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.BattleNet -{ - public class BattleNetAuthenticationHandler : AuthenticationHandler - { - - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private string tokenEndpoint = "https://eu.battle.net/oauth/token"; - private string accountUserIdEndpoint = "https://eu.api.battle.net/account/user/id"; - private string accountUserBattleTagEndpoint = "https://eu.api.battle.net/account/user/battletag"; - private string oauthAuthEndpoint = "https://eu.battle.net/oauth/authorize"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public BattleNetAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override Task InitializeCoreAsync() - { - switch (Options.Region) - { - case Region.China: - tokenEndpoint = "https://cn.battle.net/oauth/token"; - accountUserIdEndpoint = "https://cn.api.battle.net/account/user/id"; - accountUserBattleTagEndpoint = "https://cn.api.battle.net/account/user/battletag"; - oauthAuthEndpoint = "https://cn.battle.net/oauth/authorize"; - break; - case Region.Korea: - tokenEndpoint = "https://kr.battle.net/oauth/token"; - accountUserIdEndpoint = "https://kr.api.battle.net/account/user/id"; - accountUserBattleTagEndpoint = "https://kr.api.battle.net/account/user/battletag"; - oauthAuthEndpoint = "https://kr.battle.net/oauth/authorize"; - break; - case Region.Taiwan: - tokenEndpoint = "https://tw.battle.net/oauth/token"; - accountUserIdEndpoint = "https://tw.api.battle.net/account/user/id"; - accountUserBattleTagEndpoint = "https://tw.api.battle.net/account/user/battletag"; - oauthAuthEndpoint = "https://tw.battle.net/oauth/authorize"; - break; - case Region.Europe: - tokenEndpoint = "https://eu.battle.net/oauth/token"; - accountUserIdEndpoint = "https://eu.api.battle.net/account/user/id"; - accountUserBattleTagEndpoint = "https://eu.api.battle.net/account/user/battletag"; - oauthAuthEndpoint = "https://eu.battle.net/oauth/authorize"; - break; - default: - tokenEndpoint = "https://us.battle.net/oauth/token"; - accountUserIdEndpoint = "https://us.api.battle.net/account/user/id"; - accountUserBattleTagEndpoint = "https://us.api.battle.net/account/user/battletag"; - oauthAuthEndpoint = "https://us.battle.net/oauth/authorize"; - break; - } - - return Task.FromResult(true); - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - var query = Request.Query; - var 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]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, logger)) - { - return new AuthenticationTicket(null, properties); - } - - // Check for error - if (Request.Query.Get("error") != null) - return new AuthenticationTicket(null, properties); - - var requestPrefix = Request.Scheme + "://" + Request.Host; - var redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - // Build up the body for the token request - var body = new List> - { - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("code", code), - new KeyValuePair("redirect_uri", redirectUri), - new KeyValuePair("client_id", Options.ClientId), - new KeyValuePair("client_secret", Options.ClientSecret) - }; - - // Request the token - var tokenResponse = await httpClient.PostAsync(tokenEndpoint, new FormUrlEncodedContent(body)); - tokenResponse.EnsureSuccessStatusCode(); - var text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - var response = JsonConvert.DeserializeObject(text); - var accessToken = (string)response.access_token; - var expires = (string)response.expires_in; - - // Get WoW User Id - var graphResponse = await httpClient.GetAsync(accountUserIdEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken), Request.CallCancelled); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - var userId = JObject.Parse(text); - - // Get WoW BattleTag - graphResponse = await httpClient.GetAsync(accountUserBattleTagEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken), Request.CallCancelled); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - var battleTag = JObject.Parse(text); - - - var context = new BattleNetAuthenticatedContext(Context, userId, battleTag, accessToken, expires) - { - 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.BattleTag)) - { - context.Identity.AddClaim(new Claim("urn:battlenet:battletag", context.BattleTag, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.AccessToken)) - { - context.Identity.AddClaim(new Claim("urn:battlenet:accesstoken", context.AccessToken, 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(null); - } - - var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - var baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - var currentUri = - baseUri + - Request.Path + - Request.QueryString; - - var redirectUri = - baseUri + - Options.CallbackPath; - - var properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - var scope = string.Join(" ", Options.Scope); - - var state = Options.StateDataFormat.Protect(properties); - - var authorizationEndpoint = - oauthAuthEndpoint + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - - - - } - - public override async Task InvokeAsync() - { - - return await InvokeReplyPathAsync(); - - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - var ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new BattleNetReturnEndpointContext(Context, ticket) - { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, - RedirectUri = ticket.Properties.RedirectUri - }; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} diff --git a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationMiddleware.cs b/Owin.Security.Providers/BattleNet/BattleNetAuthenticationMiddleware.cs deleted file mode 100644 index acda7ca..0000000 --- a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationMiddleware.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.BattleNet -{ - public class BattleNetAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public BattleNetAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, BattleNetAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new BattleNetAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - var dataProtector = app.CreateDataProtector( - typeof(BattleNetAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new BattleNetAuthenticationHandler(httpClient, logger); - } - - private static HttpMessageHandler ResolveHttpMessageHandler(BattleNetAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} diff --git a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationOptions.cs b/Owin.Security.Providers/BattleNet/BattleNetAuthenticationOptions.cs deleted file mode 100644 index 91c1d5c..0000000 --- a/Owin.Security.Providers/BattleNet/BattleNetAuthenticationOptions.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.BattleNet -{ - public enum Region - { - Europe, - US, - Korea, - Taiwan, - China - } - - public class BattleNetAuthenticationOptions : AuthenticationOptions - { - /// - /// Initializes a new . - /// By default the scope is only wow.profile but there is also the scope for sc2.profile - /// - public BattleNetAuthenticationOptions() - : base("BattleNet") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-battlenet"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List - { - "wow.profile" - }; - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Battle.net. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Battle.net. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Battle.net. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-battlenet". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Battle.net supplied Client Id - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Battle.net supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the Battle.net Region to authenticate against. - /// - public Region Region { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IBattleNetAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - } -} diff --git a/Owin.Security.Providers/BattleNet/Constants.cs b/Owin.Security.Providers/BattleNet/Constants.cs deleted file mode 100644 index fd9c1e7..0000000 --- a/Owin.Security.Providers/BattleNet/Constants.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace Owin.Security.Providers.BattleNet -{ - internal static class Constants - { - internal const string DefaultAuthenticationType = "BattleNet"; - } -} diff --git a/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticatedContext.cs b/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticatedContext.cs deleted file mode 100644 index bb98895..0000000 --- a/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticatedContext.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.BattleNet -{ - /// - /// Contains information about the login session as well as the user . - /// - public class BattleNetAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized userId - /// The JSON-serialized battleTag - /// Battle.net Access token - /// Seconds until expiration - public BattleNetAuthenticatedContext(IOwinContext context, JObject userId, JObject battleTag, string accessToken, string expires) - : base(context) - { - JsonUserId = userId; - JsonBattleTag = battleTag; - AccessToken = accessToken; - - int expiresValue; - if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - - Id = TryGetValue(userId, "id"); - BattleTag = TryGetValue(battleTag, "battletag"); - - } - - /// - /// Gets the JSON-serialized user ID - /// - /// - /// Contains the Battle.net user ID obtained from the endpoint https://eu.api.battle.net/account/user/id - /// - public JObject JsonUserId { get; private set; } - - /// - /// Gets the JSON-serialized BattleTag - /// - /// - /// Contains the Battle.net battle tag obtained from the endpoint https://eu.api.battle.net/account/user/battletag. For more information - /// see https://dev.battle.net/io-docs - /// - public JObject JsonBattleTag { get; private set; } - - /// - /// Gets the Battle.net OAuth access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Battle.net access token expiration time - /// - public TimeSpan? ExpiresIn { get; set; } - - /// - /// Gets the Battle.net user ID - /// - public string Id { get; private set; } - - /// - /// Get Wow users battle tag - /// - public string BattleTag { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticationProvider.cs b/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticationProvider.cs deleted file mode 100644 index 1482200..0000000 --- a/Owin.Security.Providers/BattleNet/Provider/BattleNetAuthenticationProvider.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Threading.Tasks; - - -namespace Owin.Security.Providers.BattleNet -{ - /// - /// Default implementation. - /// - public class BattleNetAuthenticationProvider : IBattleNetAuthenticationProvider - { - /// - /// Initializes a - /// - public BattleNetAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Battle.net successfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public Task Authenticated(BattleNetAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public Task ReturnEndpoint(BattleNetReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} diff --git a/Owin.Security.Providers/BattleNet/Provider/BattleNetReturnEndpointContext.cs b/Owin.Security.Providers/BattleNet/Provider/BattleNetReturnEndpointContext.cs deleted file mode 100644 index d0449f4..0000000 --- a/Owin.Security.Providers/BattleNet/Provider/BattleNetReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.BattleNet -{ - /// - /// Provides context information to middleware providers. - /// - public class BattleNetReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public BattleNetReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/BattleNet/Provider/IBattleNetAuthenticationProvider.cs b/Owin.Security.Providers/BattleNet/Provider/IBattleNetAuthenticationProvider.cs deleted file mode 100644 index e045a3d..0000000 --- a/Owin.Security.Providers/BattleNet/Provider/IBattleNetAuthenticationProvider.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.BattleNet -{ - public interface IBattleNetAuthenticationProvider - { - /// - /// Invoked whenever Battle.net succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(BattleNetAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(BattleNetReturnEndpointContext context); - } -} diff --git a/Owin.Security.Providers/DeviantArt/Constants.cs b/Owin.Security.Providers/DeviantArt/Constants.cs deleted file mode 100644 index 3d1a0c2..0000000 --- a/Owin.Security.Providers/DeviantArt/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.DeviantArt -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "DeviantArt"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationExtensions.cs b/Owin.Security.Providers/DeviantArt/DeviantAuthenticationExtensions.cs deleted file mode 100644 index 3f5b8f1..0000000 --- a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using Owin.Security.Providers.DeviantArt; - -namespace Owin.Security.Providers.DeviantArt -{ - public static class DeviantArtAuthenticationExtensions - { - /// - /// Login with DeviantArt. http://yourUrl/signin-DeviantArt will be used as the redirect URI - /// - /// - /// - /// - public static IAppBuilder UseDeviantArtAuthentication(this IAppBuilder app, - DeviantArtAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(DeviantArtAuthenticationMiddleware), app, options); - - return app; - } - /// - /// Login with DeviantArt. http://yourUrl/signin-DeviantArt will be used as the redirect URI - /// - /// - /// - /// - /// - public static IAppBuilder UseDeviantArtAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseDeviantArtAuthentication(new DeviantArtAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationHandler.cs b/Owin.Security.Providers/DeviantArt/DeviantAuthenticationHandler.cs deleted file mode 100644 index 4b68278..0000000 --- a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationHandler.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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.DeviantArt; -using Owin.Security.Providers.DeviantArt.Provider; - -namespace Owin.Security.Providers.DeviantArt -{ - public class DeviantArtAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public DeviantArtAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - IList values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = string.Copy(values.First()); - } - values = query.GetValues("state"); - if (values != null && values.Count == 1) - { - state = values[0]; - } - - 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>(); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("code", code)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - - // Request the token - var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.Endpoints.TokenEndpoint); - requestMessage.Content = new FormUrlEncodedContent(body); - requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - 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; - - // Get the DeviantArt user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken)); - userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - HttpResponseMessage userResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - text = await userResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new DeviantArtAuthenticatedContext(Context, user, 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.Name)) - { - context.Identity.AddClaim(new Claim("urn:DeviantArt:name", context.Name, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - string scope = string.Join(" ", Options.Scope.Distinct()); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&response_type=" + "code" + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new DeviantArtReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationMiddleware.cs b/Owin.Security.Providers/DeviantArt/DeviantAuthenticationMiddleware.cs deleted file mode 100644 index 8792490..0000000 --- a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationMiddleware.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.DeviantArt; -using Owin.Security.Providers.DeviantArt.Provider; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.DeviantArt -{ - public class DeviantArtAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public DeviantArtAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - DeviantArtAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new DeviantArtAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (DeviantArtAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin DeviantArt middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new DeviantArtAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(DeviantArtAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationOptions.cs b/Owin.Security.Providers/DeviantArt/DeviantAuthenticationOptions.cs deleted file mode 100644 index afa8daa..0000000 --- a/Owin.Security.Providers/DeviantArt/DeviantAuthenticationOptions.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Owin.Security.Providers.DeviantArt.Provider; - -namespace Owin.Security.Providers.DeviantArt -{ - public class DeviantArtAuthenticationOptions : AuthenticationOptions - { - public class DeviantArtAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request DeviantArt access - /// - /// - /// Defaults to https://www.DeviantArt.com/oauth2/authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://www.DeviantArt.com/oauth2/token - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://www.DeviantArt.com/api/v1/oauth2/user/whoami - /// - public string UserInfoEndpoint { get; set; } - - public string DamnToken { get; set; } - } - - private const string AuthorizationEndPoint = "https://www.DeviantArt.com/oauth2/authorize"; - private const string TokenEndpoint = "https://www.DeviantArt.com/oauth2/token"; - private const string UserInfoEndpoint = "https://www.DeviantArt.com/api/v1/oauth2/user/whoami"; - private const string DamnTokenEndpoint = "https://www.DeviantArt.com/api/v1/oauth2/user/damntoken"; - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to DeviantArt. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with DeviantArt. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with DeviantArt. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-DeviantArt". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the DeviantArt supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the DeviantArt supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against DeviantArt. Overriding these endpoints allows you to use DeviantArt Enterprise for - /// authentication. - /// - public DeviantArtAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IDeviantArtAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public DeviantArtAuthenticationOptions() - : base("DeviantArt") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-deviantart"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List - { - "user" - }; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new DeviantArtAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint, - UserInfoEndpoint = UserInfoEndpoint, - DamnToken = DamnTokenEndpoint - }; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticatedContext.cs b/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticatedContext.cs deleted file mode 100644 index e3d85c9..0000000 --- a/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticatedContext.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.DeviantArt.Provider -{ - /// - /// Contains information about the login session as well as the user . - /// - public class DeviantArtAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// DeviantArt Access token - public DeviantArtAuthenticatedContext(IOwinContext context, JObject user, string accessToken) - : base(context) - { - User = user; - AccessToken = accessToken; - - Id = TryGetValue(user, "userid"); - Name = TryGetValue(user, "username"); - UserName = TryGetValue(user, "username"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the DeviantArt user obtained from the User Info endpoint. By default this is https://api.DeviantArt.com/user but it can be - /// overridden in the options - /// - public JObject User { get; private set; } - - /// - /// Gets the DeviantArt access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the DeviantArt user ID - /// - public string Id { get; private set; } - - /// - /// Gets the user's name - /// - public string Name { get; private set; } - - - /// - /// Gets the DeviantArt username - /// - public string UserName { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} diff --git a/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticationProvider.cs b/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticationProvider.cs deleted file mode 100644 index 2c61f51..0000000 --- a/Owin.Security.Providers/DeviantArt/Provider/DeviantAuthenticationProvider.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Threading.Tasks; -using Owin.Security.Providers.DeviantArt; - -namespace Owin.Security.Providers.DeviantArt.Provider -{ - /// - /// Default implementation. - /// - public class DeviantArtAuthenticationProvider : IDeviantArtAuthenticationProvider - { - /// - /// Initializes a - /// - public DeviantArtAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever DeviantArt succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(DeviantArtAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(DeviantArtReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/DeviantArt/Provider/DeviantReturnEndpointContext.cs b/Owin.Security.Providers/DeviantArt/Provider/DeviantReturnEndpointContext.cs deleted file mode 100644 index 2c4190e..0000000 --- a/Owin.Security.Providers/DeviantArt/Provider/DeviantReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.DeviantArt.Provider -{ - /// - /// Provides context information to middleware providers. - /// - public class DeviantArtReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public DeviantArtReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/DeviantArt/Provider/IDeviantAuthenticationProvider.cs b/Owin.Security.Providers/DeviantArt/Provider/IDeviantAuthenticationProvider.cs deleted file mode 100644 index 2f3bf98..0000000 --- a/Owin.Security.Providers/DeviantArt/Provider/IDeviantAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.DeviantArt.Provider -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IDeviantArtAuthenticationProvider - { - /// - /// Invoked whenever DeviantArt succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(DeviantArtAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(DeviantArtReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/Constants.cs b/Owin.Security.Providers/Dropbox/Constants.cs deleted file mode 100644 index 09904c5..0000000 --- a/Owin.Security.Providers/Dropbox/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Dropbox -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Dropbox"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/DropboxAuthenticationExtensions.cs b/Owin.Security.Providers/Dropbox/DropboxAuthenticationExtensions.cs deleted file mode 100644 index 7fca07e..0000000 --- a/Owin.Security.Providers/Dropbox/DropboxAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Dropbox -{ - public static class DropboxAuthenticationExtensions - { - public static IAppBuilder UseDropboxAuthentication(this IAppBuilder app, - DropboxAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(DropboxAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseDropboxAuthentication(this IAppBuilder app, string appKey, string appSecret) - { - return app.UseDropboxAuthentication(new DropboxAuthenticationOptions - { - AppKey = appKey, - AppSecret = appSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/DropboxAuthenticationHandler.cs b/Owin.Security.Providers/Dropbox/DropboxAuthenticationHandler.cs deleted file mode 100644 index 83614d2..0000000 --- a/Owin.Security.Providers/Dropbox/DropboxAuthenticationHandler.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.Owin; -using Microsoft.Owin.Infrastructure; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler.Encoder; -using Microsoft.Owin.Security.Infrastructure; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Dropbox -{ - public class DropboxAuthenticationHandler : AuthenticationHandler - { - private const string StateCookie = "_DropboxState"; - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://api.dropbox.com/1/oauth2/token"; - private const string UserInfoEndpoint = "https://api.dropbox.com/1/account/info"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public DropboxAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - 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]; - } - - state = Request.Cookies[StateCookie]; - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, logger)) - { - return new AuthenticationTicket(null, properties); - } - - // Check for error - if (Request.Query.Get("error") != null) - 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>(); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("code", code)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("client_id", Options.AppKey)); - body.Add(new KeyValuePair("client_secret", Options.AppSecret)); - - // Request the token - HttpResponseMessage tokenResponse = - await httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); - tokenResponse.EnsureSuccessStatusCode(); - string text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - dynamic response = JsonConvert.DeserializeObject(text); - string accessToken = (string)response.access_token; - - // Get the Dropbox user - HttpResponseMessage graphResponse = await httpClient.GetAsync( - UserInfoEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken), Request.CallCancelled); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new DropboxAuthenticatedContext(Context, user, 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.Name)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - string authorizationEndpoint = - "https://www.dropbox.com/1/oauth2/authorize" + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.AppKey) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri); - - var cookieOptions = new CookieOptions - { - HttpOnly = true, - Secure = Request.IsSecure - }; - - Response.StatusCode = 302; - Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(properties), cookieOptions); - Response.Headers.Set("Location", authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new DropboxReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/DropboxAuthenticationMiddleware.cs b/Owin.Security.Providers/Dropbox/DropboxAuthenticationMiddleware.cs deleted file mode 100644 index 11e022e..0000000 --- a/Owin.Security.Providers/Dropbox/DropboxAuthenticationMiddleware.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.Dropbox -{ - public class DropboxAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public DropboxAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - DropboxAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.AppKey)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "AppKey")); - if (String.IsNullOrWhiteSpace(Options.AppSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "AppSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new DropboxAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (DropboxAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new DropboxAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(DropboxAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/DropboxAuthenticationOptions.cs b/Owin.Security.Providers/Dropbox/DropboxAuthenticationOptions.cs deleted file mode 100644 index 3fbb1b4..0000000 --- a/Owin.Security.Providers/Dropbox/DropboxAuthenticationOptions.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.Dropbox -{ - public class DropboxAuthenticationOptions : AuthenticationOptions - { - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Dropbox - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Dropbox. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Dropbox. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-dropbox". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Dropbox supplied Application Key - /// - public string AppKey { get; set; } - - /// - /// Gets or sets the Dropbox supplied Application Secret - /// - public string AppSecret { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IDropboxAuthenticationProvider Provider { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public DropboxAuthenticationOptions() - : base("Dropbox") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-dropbox"); - AuthenticationMode = AuthenticationMode.Passive; - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticatedContext.cs b/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticatedContext.cs deleted file mode 100644 index a154eba..0000000 --- a/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticatedContext.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Dropbox -{ - /// - /// Contains information about the login session as well as the user . - /// - public class DropboxAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Dropbox Access token - public DropboxAuthenticatedContext(IOwinContext context, JObject user, string accessToken) - : base(context) - { - AccessToken = accessToken; - User = user; - - Id = TryGetValue(user, "uid"); - Name = TryGetValue(user, "display_name"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Dropbox user obtained from the endpoint https://api.dropbox.com/1/account/info - /// - public JObject User { get; private set; } - - /// - /// Gets the Dropbox OAuth access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Dropbox user ID - /// - public string Id { get; private set; } - - /// - /// The name of the user - /// - public string Name { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} diff --git a/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticationProvider.cs b/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticationProvider.cs deleted file mode 100644 index 15c7c92..0000000 --- a/Owin.Security.Providers/Dropbox/Provider/DropboxAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Dropbox -{ - /// - /// Default implementation. - /// - public class DropboxAuthenticationProvider : IDropboxAuthenticationProvider - { - /// - /// Initializes a - /// - public DropboxAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Dropbox successfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(DropboxAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(DropboxReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Dropbox/Provider/DropboxReturnEndpointContext.cs b/Owin.Security.Providers/Dropbox/Provider/DropboxReturnEndpointContext.cs deleted file mode 100644 index 040f327..0000000 --- a/Owin.Security.Providers/Dropbox/Provider/DropboxReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Dropbox -{ - /// - /// Provides context information to middleware providers. - /// - public class DropboxReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public DropboxReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Dropbox/Provider/IDropboxAuthenticationProvider.cs b/Owin.Security.Providers/Dropbox/Provider/IDropboxAuthenticationProvider.cs deleted file mode 100644 index 43d8cfb..0000000 --- a/Owin.Security.Providers/Dropbox/Provider/IDropboxAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Dropbox -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IDropboxAuthenticationProvider - { - /// - /// Invoked whenever Dropbox successfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(DropboxAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(DropboxReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/EVEOnline/Constants.cs b/Owin.Security.Providers/EVEOnline/Constants.cs deleted file mode 100644 index 96305ea..0000000 --- a/Owin.Security.Providers/EVEOnline/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.EveOnline -{ - internal static class Constants - { - internal const string DefaultAuthenticationType = "EveOnline"; - } -} diff --git a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationExtensions.cs b/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationExtensions.cs deleted file mode 100644 index 7435795..0000000 --- a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace Owin.Security.Providers.EveOnline -{ - public static class EveOnlineAuthenticationExtensions - { - public static IAppBuilder UseEveOnlineAuthentication(this IAppBuilder app, EveOnlineAuthenticationOptions options) - { - if (app == null) - throw new ArgumentException("app"); - if (options == null) - throw new ArgumentException("options"); - - app.Use(typeof(EveOnlineAuthenticationMiddleware), app, options); - - return app; - } - public static IAppBuilder UseEveOnlineAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseEveOnlineAuthentication(new EveOnlineAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} diff --git a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationHandler.cs b/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationHandler.cs deleted file mode 100644 index dac50df..0000000 --- a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationHandler.cs +++ /dev/null @@ -1,284 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.Owin.Infrastructure; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Infrastructure; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.EveOnline -{ - public class EveOnlineAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private string _tokenEndpoint; - private string _characterIdEndpoint ; - private string _oauthAuthEndpoint ; - private string _serverHost ; - - private const string _serverScheme = "https://"; - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - - public EveOnlineAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - _httpClient = httpClient; - _logger = logger; - } - - protected override Task InitializeCoreAsync() - { - return Task.Run(() => - { - switch (Options.Server) - { - case Server.Singularity: - _serverHost = "sisilogin.testeveonline.com"; - break; - default: - _serverHost = "login.eveonline.com"; - break; - } - - _tokenEndpoint = _serverScheme + _serverHost + "/oauth/token"; - _oauthAuthEndpoint = _serverScheme + _serverHost + "/oauth/authorize"; - _characterIdEndpoint = _serverScheme + _serverHost + "/oauth/verify"; - }); - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - var query = Request.Query; - var 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]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, _logger)) - { - return new AuthenticationTicket(null, properties); - } - - // Check for error - if (Request.Query.Get("error") != null) - return new AuthenticationTicket(null, properties); - - var requestPrefix = Request.Scheme + "://" + Request.Host; - var redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - // Build up the body for the token request - var body = new List> - { - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("code", code), - new KeyValuePair("redirect_uri", redirectUri), - new KeyValuePair("client_id", Options.ClientId), - new KeyValuePair("client_secret", Options.ClientSecret) - }; - - // Request the token - var tokenResponse = await _httpClient.PostAsync(_tokenEndpoint, new FormUrlEncodedContent(body)); - tokenResponse.EnsureSuccessStatusCode(); - var text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - var response = JsonConvert.DeserializeObject(text); - var accessToken = (string)response.access_token; - var refreshToken = string.Empty; - if (response.refresh_token != null) - refreshToken = (string)response.refresh_token; - - var expires = (string)response.expires_in; - - // Get character data - var graphRequest = new HttpRequestMessage() - { - Method = HttpMethod.Get, - RequestUri = new Uri(_characterIdEndpoint) - }; - - graphRequest.Headers.Add("Authorization", "Bearer " + accessToken); - graphRequest.Headers.Add("Host", _serverHost); - graphRequest.Headers.UserAgent.ParseAdd("Microsoft Owin EveOnline middleware"); - var graphResponse = await _httpClient.SendAsync(graphRequest); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - var characterId = JObject.Parse(text); - - var context = new EveOnlineAuthenticatedContext(Context, characterId, accessToken, refreshToken, expires) - { - Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType) - }; - - if (!string.IsNullOrEmpty(context.CharacterId)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.CharacterId, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.CharacterName)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.CharacterName, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.CharacterOwnerHash)) - { - context.Identity.AddClaim(new Claim("urn:eveonline:character_owner_hash", context.CharacterOwnerHash, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.AccessToken)) - { - context.Identity.AddClaim(new Claim("urn:eveonline:access_token", context.AccessToken, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.RefreshToken)) - { - context.Identity.AddClaim(new Claim("urn:eveonline:refresh_token", context.RefreshToken, 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(null); - } - - var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - var baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - var currentUri = - baseUri + - Request.Path + - Request.QueryString; - - var redirectUri = - baseUri + - Options.CallbackPath; - - var properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - var scope = string.Join(" ", Options.Scope); - - var state = Options.StateDataFormat.Protect(properties); - - var authorizationEndpoint = - _oauthAuthEndpoint + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - var ticket = await AuthenticateAsync(); - if (ticket == null) - { - _logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new EveOnlineReturnEndpointContext(Context, ticket) - { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, - RedirectUri = ticket.Properties.RedirectUri - }; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} diff --git a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationMiddleware.cs b/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationMiddleware.cs deleted file mode 100644 index 6cf75f5..0000000 --- a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationMiddleware.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.EveOnline -{ - public class EveOnlineAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient _httpClient; - private readonly ILogger _logger; - - public EveOnlineAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, EveOnlineAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - _logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new EveOnlineAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - var dataProtector = app.CreateDataProtector( - typeof(EveOnlineAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - _httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new EveOnlineAuthenticationHandler(_httpClient, _logger); - } - - private static HttpMessageHandler ResolveHttpMessageHandler(EveOnlineAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} diff --git a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationOptions.cs b/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationOptions.cs deleted file mode 100644 index 5a97764..0000000 --- a/Owin.Security.Providers/EVEOnline/EVEOnlineAuthenticationOptions.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.EveOnline -{ - public enum Server - { - Tranquility, - Singularity - } - - public class EveOnlineAuthenticationOptions : AuthenticationOptions - { - /// - /// Initializes a new . - /// By default the scope is empty, you can add ie. publicData when initializing. - /// - public EveOnlineAuthenticationOptions() - : base("EveOnline") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-eveonline"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List(); - BackchannelTimeout = TimeSpan.FromSeconds(60); - Server = Server.Tranquility; - } - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to EveOnline. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with EveOnline. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with EveOnline. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-eveonline". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets EveOnline supplied Client Id - /// - public string ClientId { get; set; } - - /// - /// Gets or sets EveOnline supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the EveOnline Server to authenticate against. - /// - public Server Server { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IEveOnlineAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - } -} diff --git a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticatedContext.cs b/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticatedContext.cs deleted file mode 100644 index 185b1e8..0000000 --- a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticatedContext.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.EveOnline -{ - /// - /// Contains information about the login session as well as the user . - /// - public class EveOnlineAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized userId - /// - /// EveOnline Access token - /// Seconds until expiration - public EveOnlineAuthenticatedContext(IOwinContext context, JObject characterData, string accessToken, string refreshToken, string expires) - : base(context) - { - JsonCharacterId = characterData; - AccessToken = accessToken; - RefreshToken = refreshToken; - - int expiresValue; - if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - - CharacterId = TryGetValue(characterData, "CharacterID"); - CharacterName = TryGetValue(characterData, "CharacterName"); - CharacterOwnerHash = TryGetValue(characterData, "CharacterOwnerHash"); - } - - /// - /// Gets the JSON-serialized user ID - /// - /// - /// Contains the EveOnline user ID - /// - public JObject JsonCharacterId { get; private set; } - - /// - /// Gets EveOnline OAuth access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets EveOnline OAuth refresh token - /// - public string RefreshToken { get; private set; } - - /// - /// Gets EveOnline access token expiration time - /// - public TimeSpan? ExpiresIn { get; set; } - - /// - /// Gets EveOnline character owner hash. It changes only if character is transfered - /// to other account. - /// - public string CharacterOwnerHash { get; private set; } - - /// - /// Gets EveOnline character ID - /// - public string CharacterId { get; private set; } - - /// - /// Gets the EveOnline character name - /// - public string CharacterName { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticationProvider.cs b/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticationProvider.cs deleted file mode 100644 index efec8be..0000000 --- a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineAuthenticationProvider.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Threading.Tasks; - - -namespace Owin.Security.Providers.EveOnline -{ - /// - /// Default implementation. - /// - public class EveOnlineAuthenticationProvider : IEveOnlineAuthenticationProvider - { - /// - /// Initializes a - /// - public EveOnlineAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Battle.net successfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public Task Authenticated(EveOnlineAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public Task ReturnEndpoint(EveOnlineReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} diff --git a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineReturnEndpointContext.cs b/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineReturnEndpointContext.cs deleted file mode 100644 index 9fcdc23..0000000 --- a/Owin.Security.Providers/EVEOnline/Provider/EVEOnlineReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.EveOnline -{ - /// - /// Provides context information to middleware providers. - /// - public class EveOnlineReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public EveOnlineReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/EVEOnline/Provider/IEVEOnlineAuthenticationProvider.cs b/Owin.Security.Providers/EVEOnline/Provider/IEVEOnlineAuthenticationProvider.cs deleted file mode 100644 index 1355655..0000000 --- a/Owin.Security.Providers/EVEOnline/Provider/IEVEOnlineAuthenticationProvider.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.EveOnline -{ - public interface IEveOnlineAuthenticationProvider - { - /// - /// Invoked whenever Battle.net succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(EveOnlineAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(EveOnlineReturnEndpointContext context); - } -} diff --git a/Owin.Security.Providers/Flickr/Constants.cs b/Owin.Security.Providers/Flickr/Constants.cs deleted file mode 100644 index e5a32d3..0000000 --- a/Owin.Security.Providers/Flickr/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Flickr -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Flickr"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Flickr/FlickrAuthenticationExtensions.cs b/Owin.Security.Providers/Flickr/FlickrAuthenticationExtensions.cs deleted file mode 100644 index b1fe1d8..0000000 --- a/Owin.Security.Providers/Flickr/FlickrAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Flickr -{ - public static class FlickrAuthenticationExtensions - { - public static IAppBuilder UseFlickrAuthentication(this IAppBuilder app, - FlickrAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(FlickrAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseFlickrAuthentication(this IAppBuilder app, string appKey, string appSecret) - { - return app.UseFlickrAuthentication(new FlickrAuthenticationOptions - { - AppKey = appKey, - AppSecret = appSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Flickr/FlickrAuthenticationHandler.cs b/Owin.Security.Providers/Flickr/FlickrAuthenticationHandler.cs deleted file mode 100644 index fa920c4..0000000 --- a/Owin.Security.Providers/Flickr/FlickrAuthenticationHandler.cs +++ /dev/null @@ -1,367 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Runtime.InteropServices; -using System.Security.Claims; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Owin; -using Microsoft.Owin.Helpers; -using Microsoft.Owin.Infrastructure; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Infrastructure; -using Newtonsoft.Json.Linq; -using Owin.Security.Providers.Flickr.Messages; - -namespace Owin.Security.Providers.Flickr -{ - internal class FlickrAuthenticationHandler : AuthenticationHandler - { - private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - private const string StateCookie = "__FlickrState"; - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string RequestTokenEndpoint = "https://www.flickr.com/services/oauth/request_token"; - private const string AuthenticationEndpoint = "https://www.flickr.com/services/oauth/authorize?oauth_token="; - private const string AccessTokenEndpoint = "https://www.flickr.com/services/oauth/access_token"; - - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public FlickrAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - public override async Task InvokeAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - return await InvokeReturnPathAsync(); - } - return false; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - try - { - IReadableStringCollection query = Request.Query; - string protectedRequestToken = Request.Cookies[StateCookie]; - - RequestToken requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken); - - if (requestToken == null) - { - logger.WriteWarning("Invalid state"); - return null; - } - - properties = requestToken.Properties; - - string returnedToken = query.Get("oauth_token"); - if (string.IsNullOrWhiteSpace(returnedToken)) - { - logger.WriteWarning("Missing oauth_token"); - return new AuthenticationTicket(null, properties); - } - - if (returnedToken != requestToken.Token) - { - logger.WriteWarning("Unmatched token"); - return new AuthenticationTicket(null, properties); - } - - string oauthVerifier = query.Get("oauth_verifier"); - if (string.IsNullOrWhiteSpace(oauthVerifier)) - { - logger.WriteWarning("Missing or blank oauth_verifier"); - return new AuthenticationTicket(null, properties); - } - - AccessToken accessToken = await ObtainAccessTokenAsync(Options.AppKey, Options.AppSecret, requestToken, oauthVerifier); - - var context = new FlickrAuthenticatedContext(Context, accessToken); - - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - if (!String.IsNullOrEmpty(context.UserId)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.UserId, - XmlSchemaString, Options.AuthenticationType)); - } - if(!String.IsNullOrEmpty(context.UserName)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName, - XmlSchemaString, Options.AuthenticationType)); - } - if (!String.IsNullOrEmpty(context.FullName)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.FullName, - XmlSchemaString, Options.AuthenticationType)); - } - context.Properties = requestToken.Properties; - - Response.Cookies.Delete(StateCookie); - - await Options.Provider.Authenticated(context); - - return new AuthenticationTicket(context.Identity, context.Properties); - } - catch (Exception ex) - { - logger.WriteError("Authentication failed", ex); - return new AuthenticationTicket(null, properties); - } - } - - protected override async Task ApplyResponseChallengeAsync() - { - if (Response.StatusCode != 401) - { - return; - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string requestPrefix = Request.Scheme + "://" + Request.Host; - string callBackUrl = requestPrefix + RequestPathBase + Options.CallbackPath; - - AuthenticationProperties extra = challenge.Properties; - if (string.IsNullOrEmpty(extra.RedirectUri)) - { - extra.RedirectUri = requestPrefix + Request.PathBase + Request.Path + Request.QueryString; - } - - RequestToken requestToken = await ObtainRequestTokenAsync(Options.AppKey, Options.AppSecret, callBackUrl, extra); - - if (requestToken.CallbackConfirmed) - { - string FlickrAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token + "&perms=" + Options.Scope; - - var cookieOptions = new CookieOptions - { - HttpOnly = true, - Secure = Request.IsSecure - }; - - Response.StatusCode = 302; - Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions); - Response.Headers.Set("Location", FlickrAuthenticationEndpoint); - } - else - { - logger.WriteError("requestToken CallbackConfirmed!=true"); - } - } - } - - public async Task InvokeReturnPathAsync() - { - AuthenticationTicket model = await AuthenticateAsync(); - if (model == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new FlickrReturnEndpointContext(Context, model) - { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, - RedirectUri = model.Properties.RedirectUri - }; - model.Properties.RedirectUri = null; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && context.Identity != null) - { - ClaimsIdentity signInIdentity = context.Identity; - if (!string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, signInIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - context.RedirectUri = WebUtilities.AddQueryString(context.RedirectUri, "error", "access_denied"); - } - Response.Redirect(context.RedirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - - private async Task ObtainRequestTokenAsync(string AppKey, string AppSecret, string callBackUri, AuthenticationProperties properties) - { - logger.WriteVerbose("ObtainRequestToken"); - - string nonce = Guid.NewGuid().ToString("N"); - - var authorizationParts = new SortedDictionary - { - { "oauth_callback", callBackUri }, - { "oauth_consumer_key", AppKey }, - { "oauth_nonce", nonce }, - { "oauth_signature_method", "HMAC-SHA1" }, - { "oauth_timestamp", GenerateTimeStamp() }, - { "oauth_version", "1.0" } - }; - - var parameterBuilder = new StringBuilder(); - foreach (var authorizationKey in authorizationParts) - { - parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); - } - parameterBuilder.Length--; - string parameterString = parameterBuilder.ToString(); - - var canonicalizedRequestBuilder = new StringBuilder(); - canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); - canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(RequestTokenEndpoint)); - canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); - - string signature = ComputeSignature(AppSecret, null, canonicalizedRequestBuilder.ToString()); - authorizationParts.Add("oauth_signature", signature); - - //-- - var authorizationHeaderBuilder = new StringBuilder(); - authorizationHeaderBuilder.Append("OAuth "); - foreach (var authorizationPart in authorizationParts) - { - authorizationHeaderBuilder.AppendFormat( - "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); - } - authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; - - var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint); - request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); - - HttpResponseMessage response = await httpClient.SendAsync(request, Request.CallCancelled); - response.EnsureSuccessStatusCode(); - string responseText = await response.Content.ReadAsStringAsync(); - - IFormCollection responseParameters = WebHelpers.ParseForm(responseText); - if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.InvariantCulture)) - { - return new RequestToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties }; - } - - return new RequestToken(); - } - - private async Task ObtainAccessTokenAsync(string AppKey, string AppSecret, RequestToken token, string verifier) - { - logger.WriteVerbose("ObtainAccessToken"); - - string nonce = Guid.NewGuid().ToString("N"); - - var authorizationParts = new SortedDictionary - { - { "oauth_consumer_key", AppKey }, - { "oauth_nonce", nonce }, - { "oauth_signature_method", "HMAC-SHA1" }, - { "oauth_token", token.Token }, - { "oauth_timestamp", GenerateTimeStamp() }, - { "oauth_verifier", verifier }, - { "oauth_version", "1.0" }, - }; - - var parameterBuilder = new StringBuilder(); - foreach (var authorizationKey in authorizationParts) - { - parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); - } - parameterBuilder.Length--; - string parameterString = parameterBuilder.ToString(); - - var canonicalizedRequestBuilder = new StringBuilder(); - canonicalizedRequestBuilder.Append(HttpMethod.Post.Method); - canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint)); - canonicalizedRequestBuilder.Append("&"); - canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString)); - - string signature = ComputeSignature(AppSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString()); - authorizationParts.Add("oauth_signature", signature); - - var authorizationHeaderBuilder = new StringBuilder(); - authorizationHeaderBuilder.Append("OAuth "); - foreach (var authorizationPart in authorizationParts) - { - authorizationHeaderBuilder.AppendFormat( - "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); - } - authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; - - var request = new HttpRequestMessage(HttpMethod.Post, AccessTokenEndpoint); - request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); - - var formPairs = new List>() - { - new KeyValuePair("oauth_verifier", verifier) - }; - - request.Content = new FormUrlEncodedContent(formPairs); - - HttpResponseMessage response = await httpClient.SendAsync(request, Request.CallCancelled); - - if (!response.IsSuccessStatusCode) - { - logger.WriteError("AccessToken request failed with a status code of " + response.StatusCode); - response.EnsureSuccessStatusCode(); // throw - } - - string responseText = await response.Content.ReadAsStringAsync(); - IFormCollection responseParameters = WebHelpers.ParseForm(responseText); - - return new AccessToken - { - Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), - TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), - UserId = Uri.UnescapeDataString(responseParameters["user_nsid"]), - UserName = Uri.UnescapeDataString(responseParameters["username"]), - FullName = Uri.UnescapeDataString(responseParameters["fullname"]), - }; - } - - private static string GenerateTimeStamp() - { - TimeSpan secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch; - return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); - } - - private static string ComputeSignature(string AppSecret, string tokenSecret, string signatureData) - { - using (var algorithm = new HMACSHA1()) - { - algorithm.Key = Encoding.ASCII.GetBytes( - string.Format(CultureInfo.InvariantCulture, - "{0}&{1}", - Uri.EscapeDataString(AppSecret), - string.IsNullOrEmpty(tokenSecret) ? string.Empty : Uri.EscapeDataString(tokenSecret))); - byte[] hash = algorithm.ComputeHash(Encoding.ASCII.GetBytes(signatureData)); - return Convert.ToBase64String(hash); - } - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Flickr/FlickrAuthenticationMiddleware.cs b/Owin.Security.Providers/Flickr/FlickrAuthenticationMiddleware.cs deleted file mode 100644 index 3eb4be0..0000000 --- a/Owin.Security.Providers/Flickr/FlickrAuthenticationMiddleware.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; -using Owin.Security.Providers.Flickr.Messages; -using Microsoft.Owin.Security.DataHandler.Encoder; - -namespace Owin.Security.Providers.Flickr -{ - public class FlickrAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public FlickrAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - FlickrAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.AppKey)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "AppKey")); - if (String.IsNullOrWhiteSpace(Options.AppSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "AppSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new FlickrAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof(FlickrAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new SecureDataFormat( - Serializers.RequestToken, - dataProtector, - TextEncodings.Base64Url); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new FlickrAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(FlickrAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Flickr/FlickrAuthenticationOptions.cs b/Owin.Security.Providers/Flickr/FlickrAuthenticationOptions.cs deleted file mode 100644 index 9dff4c5..0000000 --- a/Owin.Security.Providers/Flickr/FlickrAuthenticationOptions.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Owin.Security.Providers.Flickr.Messages; - -namespace Owin.Security.Providers.Flickr { - public class FlickrAuthenticationOptions : AuthenticationOptions - { - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Flickr. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Flickr. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Flickr. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-Flickr". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Flickr supplied App Key - /// - public string AppKey { get; set; } - - /// - /// Gets or sets the Flickr supplied App Secret - /// - public string AppSecret { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IFlickrAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public string Scope { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public FlickrAuthenticationOptions() - : base("Flickr") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-flickr"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = "read"; - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - } -} diff --git a/Owin.Security.Providers/Flickr/Messages/AccessToken.cs b/Owin.Security.Providers/Flickr/Messages/AccessToken.cs deleted file mode 100644 index 40c10dd..0000000 --- a/Owin.Security.Providers/Flickr/Messages/AccessToken.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Owin.Security.Providers.Flickr.Messages -{ - /// - /// Flickr access token - /// - public class AccessToken : RequestToken - { - /// - /// Gets or sets the Flickr User ID - /// - public string UserId { get; set; } - - /// - /// Gets or sets the Flickr User Name - /// - public string UserName { get; set; } - - /// - /// Gets or sets the Flickr User Full Name - /// - public string FullName { get; set; } - } -} diff --git a/Owin.Security.Providers/Flickr/Messages/RequestToken.cs b/Owin.Security.Providers/Flickr/Messages/RequestToken.cs deleted file mode 100644 index 74748aa..0000000 --- a/Owin.Security.Providers/Flickr/Messages/RequestToken.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.Flickr.Messages -{ - /// - /// Yahoo request token - /// - public class RequestToken - { - /// - /// Gets or sets the Yahoo token - /// - public string Token { get; set; } - - /// - /// Gets or sets the Yahoo token secret - /// - public string TokenSecret { get; set; } - - public bool CallbackConfirmed { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - } -} diff --git a/Owin.Security.Providers/Flickr/Messages/RequestTokenSerializer.cs b/Owin.Security.Providers/Flickr/Messages/RequestTokenSerializer.cs deleted file mode 100644 index 56b0253..0000000 --- a/Owin.Security.Providers/Flickr/Messages/RequestTokenSerializer.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler.Serializer; - -namespace Owin.Security.Providers.Flickr.Messages -{ - /// - /// Serializes and deserializes Yahoo request and access tokens so that they can be used by other application components. - /// - public class RequestTokenSerializer : IDataSerializer - { - private const int FormatVersion = 1; - - /// - /// Serialize a request token - /// - /// The token to serialize - /// A byte array containing the serialized token - [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] - public virtual byte[] Serialize(RequestToken model) - { - using (var memory = new MemoryStream()) - { - using (var writer = new BinaryWriter(memory)) - { - Write(writer, model); - writer.Flush(); - return memory.ToArray(); - } - } - } - - /// - /// Deserializes a request token - /// - /// A byte array containing the serialized token - /// The Yahoo request token - [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Dispose is idempotent")] - public virtual RequestToken Deserialize(byte[] data) - { - using (var memory = new MemoryStream(data)) - { - using (var reader = new BinaryReader(memory)) - { - return Read(reader); - } - } - } - - /// - /// Writes a Yahoo request token as a series of bytes. Used by the method. - /// - /// The writer to use in writing the token - /// The token to write - public static void Write(BinaryWriter writer, RequestToken token) - { - if (writer == null) - { - throw new ArgumentNullException("writer"); - } - if (token == null) - { - throw new ArgumentNullException("token"); - } - - writer.Write(FormatVersion); - writer.Write(token.Token); - writer.Write(token.TokenSecret); - writer.Write(token.CallbackConfirmed); - PropertiesSerializer.Write(writer, token.Properties); - } - - /// - /// Reads a Yahoo request token from a series of bytes. Used by the method. - /// - /// The reader to use in reading the token bytes - /// The token - public static RequestToken Read(BinaryReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - if (reader.ReadInt32() != FormatVersion) - { - return null; - } - - string token = reader.ReadString(); - string tokenSecret = reader.ReadString(); - bool callbackConfirmed = reader.ReadBoolean(); - AuthenticationProperties properties = PropertiesSerializer.Read(reader); - if (properties == null) - { - return null; - } - - return new RequestToken { Token = token, TokenSecret = tokenSecret, CallbackConfirmed = callbackConfirmed, Properties = properties }; - } - } -} diff --git a/Owin.Security.Providers/Flickr/Messages/Serializers.cs b/Owin.Security.Providers/Flickr/Messages/Serializers.cs deleted file mode 100644 index bcf577d..0000000 --- a/Owin.Security.Providers/Flickr/Messages/Serializers.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin.Security.DataHandler.Serializer; - -namespace Owin.Security.Providers.Flickr.Messages -{ - /// - /// Provides access to a request token serializer - /// - public static class Serializers - { - static Serializers() - { - RequestToken = new RequestTokenSerializer(); - } - - /// - /// Gets or sets a statically-avaliable serializer object. The value for this property will be by default. - /// - public static IDataSerializer RequestToken { get; set; } - } -} diff --git a/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticatedContext.cs b/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticatedContext.cs deleted file mode 100644 index d8bba84..0000000 --- a/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticatedContext.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Linq; -using System.Runtime.InteropServices; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; -using Owin.Security.Providers.Flickr.Messages; - -namespace Owin.Security.Providers.Flickr { - /// - /// Contains information about the login session as well as the user . - /// - public class FlickrAuthenticatedContext : BaseContext { - /// - /// Initializes a - /// - /// The OWIN environment - /// Flick access toke - public FlickrAuthenticatedContext(IOwinContext context, AccessToken accessToken) - : base(context) - { - FullName = accessToken.FullName; - UserId = accessToken.UserId; - UserName = accessToken.UserName; - AccessToken = accessToken.Token; - AccessTokenSecret = accessToken.TokenSecret; - } - - /// - /// Gets user full name - /// - public string FullName { get; private set; } - - /// - /// Gets the Flickr user ID - /// - public string UserId { get; private set; } - - /// - /// Gets the Flickr username - /// - public string UserName { get; private set; } - - /// - /// Gets the Flickr access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Flickr access token secret - /// - public string AccessTokenSecret { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - } -} diff --git a/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticationProvider.cs b/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticationProvider.cs deleted file mode 100644 index c043f44..0000000 --- a/Owin.Security.Providers/Flickr/Provider/FlickrAuthenticationProvider.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Flickr { - /// - /// Default implementation. - /// - public class FlickrAuthenticationProvider : IFlickrAuthenticationProvider { - /// - /// Initializes a - /// - public FlickrAuthenticationProvider() { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Flickr succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(FlickrAuthenticatedContext context) { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(FlickrReturnEndpointContext context) { - return OnReturnEndpoint(context); - } - } -} diff --git a/Owin.Security.Providers/Flickr/Provider/FlickrReturnEndpointContext.cs b/Owin.Security.Providers/Flickr/Provider/FlickrReturnEndpointContext.cs deleted file mode 100644 index 1b9ad25..0000000 --- a/Owin.Security.Providers/Flickr/Provider/FlickrReturnEndpointContext.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Flickr { - /// - /// Provides context information to middleware providers. - /// - public class FlickrReturnEndpointContext : ReturnEndpointContext { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public FlickrReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) { - } - } -} diff --git a/Owin.Security.Providers/Flickr/Provider/IFlickrAuthenticationProvider.cs b/Owin.Security.Providers/Flickr/Provider/IFlickrAuthenticationProvider.cs deleted file mode 100644 index 96d54d7..0000000 --- a/Owin.Security.Providers/Flickr/Provider/IFlickrAuthenticationProvider.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Flickr { - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IFlickrAuthenticationProvider { - /// - /// Invoked whenever Flickr succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(FlickrAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(FlickrReturnEndpointContext context); - } -} diff --git a/Owin.Security.Providers/Foursquare/Constants.cs b/Owin.Security.Providers/Foursquare/Constants.cs deleted file mode 100644 index 5ee96d5..0000000 --- a/Owin.Security.Providers/Foursquare/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Foursquare -{ - internal static class Constants - { - internal const string DefaultAuthenticationType = "Foursquare"; - } -} diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs deleted file mode 100644 index f92372a..0000000 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Foursquare -{ - public static class FoursquareAuthenticationExtensions - { - public static IAppBuilder UseFoursquareAuthentication(this IAppBuilder app, FoursquareAuthenticationOptions options) - { - if (app == null) - { - throw new ArgumentNullException("app"); - } - - if (options == null) - { - throw new ArgumentNullException("options"); - } - - return app.Use(typeof(FoursquareAuthenticationMiddleware), app, options); - } - - public static IAppBuilder UseFoursquareAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseFoursquareAuthentication(new FoursquareAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs deleted file mode 100644 index cfe1140..0000000 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationHandler.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.Owin.Infrastructure; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Infrastructure; -using Newtonsoft.Json.Linq; -using Owin.Security.Providers.Foursquare.Provider; - -namespace Owin.Security.Providers.Foursquare -{ - public class FoursquareAuthenticationHandler : AuthenticationHandler - { - private const string AuthorizationEndpoint = "https://foursquare.com/oauth2/authenticate"; - private const string TokenEndpoint = "https://foursquare.com/oauth2/access_token"; - private const string GraphApiEndpoint = "https://api.foursquare.com/v2/users/self"; - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private static readonly DateTime VersionDate = new DateTime(2015, 3, 19); - - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - - public FoursquareAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this._httpClient = httpClient; - this._logger = logger; - } - - public override async Task InvokeAsync() - { - if ((string.IsNullOrEmpty(this.Options.CallbackPath) == false) && (this.Options.CallbackPath == this.Request.Path.ToString())) - { - return await this.InvokeReturnPathAsync(); - } - - return false; - } - - protected override async Task AuthenticateCoreAsync() - { - this._logger.WriteVerbose("AuthenticateCore"); - - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - var query = this.Request.Query; - var 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]; - } - - properties = this.Options.StateDataFormat.Unprotect(state); - - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (this.ValidateCorrelationId(properties, this._logger) == false) - { - return new AuthenticationTicket(null, properties); - } - - var tokenRequestParameters = new List>() - { - new KeyValuePair("client_id", this.Options.ClientId), - new KeyValuePair("client_secret", this.Options.ClientSecret), - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("redirect_uri", this.GenerateRedirectUri()), - new KeyValuePair("code", code), - }; - - var requestContent = new FormUrlEncodedContent(tokenRequestParameters); - - var response = await this._httpClient.PostAsync(TokenEndpoint, requestContent, this.Request.CallCancelled); - response.EnsureSuccessStatusCode(); - - var oauthTokenResponse = await response.Content.ReadAsStringAsync(); - - var oauth2Token = JObject.Parse(oauthTokenResponse); - var accessToken = oauth2Token["access_token"].Value(); - - if (string.IsNullOrWhiteSpace(accessToken) == true) - { - this._logger.WriteWarning("Access token was not found"); - return new AuthenticationTicket(null, properties); - } - - var graphResponse = await this._httpClient.GetAsync(GraphApiEndpoint + "?oauth_token=" + Uri.EscapeDataString(accessToken) + "&m=foursquare&v=" + VersionDate.ToString("yyyyyMMdd"), this.Request.CallCancelled); - graphResponse.EnsureSuccessStatusCode(); - - var accountstring = await graphResponse.Content.ReadAsStringAsync(); - var accountInformation = JObject.Parse(accountstring); - var user = (JObject)accountInformation["response"]["user"]; - - var context = new FoursquareAuthenticatedContext(this.Context, user, accessToken); - - context.Identity = new ClaimsIdentity( - new[] - { - new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, this.Options.AuthenticationType), - new Claim(ClaimTypes.Name, context.Name, XmlSchemaString, this.Options.AuthenticationType), - new Claim("urn:foursquare:id", context.Id, XmlSchemaString, this.Options.AuthenticationType), - new Claim("urn:foursquare:name", context.Name, XmlSchemaString, this.Options.AuthenticationType), - }, - this.Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - - if (string.IsNullOrWhiteSpace(context.Email) == false) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, this.Options.AuthenticationType)); - } - - if (string.IsNullOrWhiteSpace(context.Twitter) == false) - { - context.Identity.AddClaim(new Claim("urn:foursquare:twitter", context.Twitter, XmlSchemaString, this.Options.AuthenticationType)); - } - - await this.Options.Provider.Authenticated(context); - - context.Properties = properties; - - return new AuthenticationTicket(context.Identity, context.Properties); - } - catch (Exception ex) - { - this._logger.WriteWarning("Authentication failed", ex); - return new AuthenticationTicket(null, properties); - } - } - - protected override Task ApplyResponseChallengeAsync() - { - this._logger.WriteVerbose("ApplyResponseChallenge"); - - if (this.Response.StatusCode != (int)HttpStatusCode.Unauthorized) - { - return Task.FromResult(null); - } - - var challenge = Helper.LookupChallenge(this.Options.AuthenticationType, this.Options.AuthenticationMode); - - if (challenge != null) - { - var baseUri = this.Request.Scheme + Uri.SchemeDelimiter + this.Request.Host + this.Request.PathBase; - var currentUri = baseUri + this.Request.Path + this.Request.QueryString; - var redirectUri = baseUri + this.Options.CallbackPath; - - var extra = challenge.Properties; - - if (string.IsNullOrEmpty(extra.RedirectUri) == true) - { - extra.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - this.GenerateCorrelationId(extra); - - var state = this.Options.StateDataFormat.Protect(extra); - - var authorizationEndpoint = AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(this.Options.ClientId) + - "&response_type=code" + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&state=" + Uri.EscapeDataString(state); - - this.Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public async Task InvokeReturnPathAsync() - { - this._logger.WriteVerbose("InvokeReturnPath"); - - var model = await this.AuthenticateAsync(); - - var context = new FoursquareReturnEndpointContext(Context, model); - context.SignInAsAuthenticationType = this.Options.SignInAsAuthenticationType; - context.RedirectUri = model.Properties.RedirectUri; - - model.Properties.RedirectUri = null; - - await this.Options.Provider.ReturnEndpoint(context); - - if ((context.SignInAsAuthenticationType != null) && (context.Identity != null)) - { - var signInIdentity = context.Identity; - - if (string.Equals(signInIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal) == false) - { - signInIdentity = new ClaimsIdentity(signInIdentity.Claims, context.SignInAsAuthenticationType, signInIdentity.NameClaimType, signInIdentity.RoleClaimType); - } - - this.Context.Authentication.SignIn(context.Properties, signInIdentity); - } - - if ((context.IsRequestCompleted == false) && (context.RedirectUri != null)) - { - if (context.Identity == null) - { - context.RedirectUri = WebUtilities.AddQueryString(context.RedirectUri, "error", "access_denied"); - } - - this.Response.Redirect(context.RedirectUri); - - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - - private string GenerateRedirectUri() - { - var requestPrefix = this.Request.Scheme + "://" + this.Request.Host; - var redirectUri = requestPrefix + this.RequestPathBase + this.Options.CallbackPath; - return redirectUri; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs deleted file mode 100644 index 300e5f2..0000000 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationMiddleware.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Foursquare.Provider; - -namespace Owin.Security.Providers.Foursquare -{ - public class FoursquareAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - - public FoursquareAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, FoursquareAuthenticationOptions options) - : base(next, options) - { - if (string.IsNullOrWhiteSpace(this.Options.ClientId) == true) - { - throw new ArgumentException("The 'ClientId' must be provided."); - } - - if (string.IsNullOrWhiteSpace(this.Options.ClientSecret) == true) - { - throw new ArgumentException("The 'ClientSecret' option must be provided."); - } - - this._logger = app.CreateLogger(); - - if (this.Options.Provider == null) - { - this.Options.Provider = new FoursquareAuthenticationProvider(); - } - - if (this.Options.StateDataFormat == null) - { - var dataProtector = app.CreateDataProtector(typeof(FoursquareAuthenticationMiddleware).FullName, this.Options.AuthenticationType, "v1"); - this.Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (string.IsNullOrEmpty(this.Options.SignInAsAuthenticationType) == true) - { - this.Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - } - - this._httpClient = new HttpClient(ResolveHttpMessageHandler(this.Options)); - this._httpClient.Timeout = this.Options.BackchannelTimeout; - this._httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new FoursquareAuthenticationHandler(this._httpClient, this._logger); - } - - private static HttpMessageHandler ResolveHttpMessageHandler(FoursquareAuthenticationOptions options) - { - var handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - - if (webRequestHandler == null) - { - throw new InvalidOperationException("Validator Handler Mismatch"); - } - - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs b/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs deleted file mode 100644 index 41d8ab9..0000000 --- a/Owin.Security.Providers/Foursquare/FoursquareAuthenticationOptions.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin.Security; -using Owin.Security.Providers.Foursquare.Provider; - -namespace Owin.Security.Providers.Foursquare -{ - public class FoursquareAuthenticationOptions : AuthenticationOptions - { - /// - /// Initializes a new - /// - public FoursquareAuthenticationOptions() - : base(Constants.DefaultAuthenticationType) - { - this.Caption = Constants.DefaultAuthenticationType; - this.CallbackPath = "/signin-foursquare"; - this.AuthenticationMode = AuthenticationMode.Passive; - this.BackchannelTimeout = TimeSpan.FromSeconds(60); - } - - /// - /// Gets or sets the Foursquare supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Foursquare supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Foursquare. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Foursquare. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Foursquare. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-foursquare". - /// - public string CallbackPath { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IFoursquareAuthenticationProvider Provider { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return this.Description.Caption; } - set { this.Description.Caption = value; } - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs deleted file mode 100644 index 04b9a28..0000000 --- a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticatedContext.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Foursquare.Provider -{ - /// - /// Contains information about the login session as well as the user . - /// - public class FoursquareAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Foursquare Access token - public FoursquareAuthenticatedContext(IOwinContext context, JObject user, string accessToken) - : base(context) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - this.User = user; - this.AccessToken = accessToken; - - var userId = this.User["id"]; - - if (userId == null) - { - throw new ArgumentException("The user does not have an id.", "user"); - } - - this.Id = TryGetValue(user, "id"); - this.FirstName = TryGetValue(user, "firstName"); - this.LastName = TryGetValue(user, "lastName"); - this.Name = this.FirstName + " " + this.LastName; - this.Gender = TryGetValue(user, "gender"); - this.Photo = (JObject)user["photo"]; - this.Friends = TryGetValue(user, "friends"); - this.HomeCity = TryGetValue(user, "homeCity"); - this.Bio = TryGetValue(user, "bio"); - this.Contact = (JObject)user["contact"]; - this.Phone = TryGetValue(Contact, "phone"); - this.Email = TryGetValue(Contact, "email"); - this.Twitter = TryGetValue(Contact, "twitter"); - this.Facebook = TryGetValue(Contact, "facebook"); - this.Badges = TryGetValue(user, "badges"); - this.Mayorships = TryGetValue(user, "mayorships"); - this.Checkins = TryGetValue(user, "checkins"); - this.Photos = TryGetValue(user, "photos"); - this.Scores = TryGetValue(user, "scores"); - this.Link = "https://foursquare.com/user/" + this.Id; - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Foursquare user obtained from the User Info endpoint https://api.foursquare.com/v2/users/self - /// - public JObject User { get; private set; } - /// - /// Gets the Foursquare access token - /// - public string AccessToken { get; private set; } - /// - /// Gets the Foursquare user ID - /// - public string Id { get; private set; } - /// - /// Gets the user's first name - /// - public string FirstName { get; private set; } - /// - /// Gets the user's last name - /// - public string LastName { get; private set; } - /// - /// Gets the user's full name - /// - public string Name { get; private set; } - /// - /// Gets the user's gender - /// - public string Gender { get; private set; } - /// - /// Gets the user's photo - /// - public JObject Photo { get; private set; } - /// - /// Gets the user's friends - /// - public string Friends { get; private set; } - /// - /// Gets the user's home city - /// - public string HomeCity { get; private set; } - /// - /// Gets the user's biography - /// - public string Bio { get; private set; } - /// - /// Gets the user's contact - /// - public JObject Contact { get; private set; } - /// - /// Gets the user's phone - /// - public string Phone { get; private set; } - /// - /// Gets the user's email - /// - public string Email { get; private set; } - /// - /// Gets the user's Twitter handle - /// - public string Twitter { get; private set; } - /// - /// Gets the user's Facebook id - /// - public string Facebook { get; private set; } - /// - /// Gets the user's badges - /// - public string Badges { get; private set; } - /// - /// Gets the user's mayorships - /// - public string Mayorships { get; private set; } - /// - /// Gets the user's checkins - /// - public string Checkins { get; private set; } - /// - /// Gets the user's photos - /// - public string Photos { get; private set; } - /// - /// Gets the user's scores - /// - public string Scores { get; private set; } - /// - /// Gets the user's link - /// - public string Link { get; private set; } - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs b/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs deleted file mode 100644 index 841cf2e..0000000 --- a/Owin.Security.Providers/Foursquare/Provider/FoursquareAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Foursquare.Provider -{ - /// - /// Default implementation. - /// - public class FoursquareAuthenticationProvider : IFoursquareAuthenticationProvider - { - /// - /// Initializes a - /// - public FoursquareAuthenticationProvider() - { - this.OnAuthenticated = context => Task.FromResult(null); - this.OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Foursquare succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(FoursquareAuthenticatedContext context) - { - return this.OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(FoursquareReturnEndpointContext context) - { - return this.OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/Provider/FoursquareReturnEndpointContext.cs b/Owin.Security.Providers/Foursquare/Provider/FoursquareReturnEndpointContext.cs deleted file mode 100644 index 6ec9a33..0000000 --- a/Owin.Security.Providers/Foursquare/Provider/FoursquareReturnEndpointContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Foursquare.Provider -{ - /// - /// Provides context information to middleware providers. - /// - public class FoursquareReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public FoursquareReturnEndpointContext(IOwinContext context, AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Foursquare/Provider/IFoursquareAuthenticationProvider.cs b/Owin.Security.Providers/Foursquare/Provider/IFoursquareAuthenticationProvider.cs deleted file mode 100644 index c46a554..0000000 --- a/Owin.Security.Providers/Foursquare/Provider/IFoursquareAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Foursquare.Provider -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IFoursquareAuthenticationProvider - { - /// - /// Invoked whenever Foursquare succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(FoursquareAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(FoursquareReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/GitHub/GitHubAuthenticationHandler.cs b/Owin.Security.Providers/GitHub/GitHubAuthenticationHandler.cs index f52bfbb..0b9cdbb 100644 --- a/Owin.Security.Providers/GitHub/GitHubAuthenticationHandler.cs +++ b/Owin.Security.Providers/GitHub/GitHubAuthenticationHandler.cs @@ -103,10 +103,6 @@ protected override async Task AuthenticateCoreAsync() { 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.Name)) { context.Identity.AddClaim(new Claim("urn:github:name", context.Name, XmlSchemaString, Options.AuthenticationType)); diff --git a/Owin.Security.Providers/GitHub/Provider/GitHubAuthenticatedContext.cs b/Owin.Security.Providers/GitHub/Provider/GitHubAuthenticatedContext.cs index c4ccea8..dec8d80 100644 --- a/Owin.Security.Providers/GitHub/Provider/GitHubAuthenticatedContext.cs +++ b/Owin.Security.Providers/GitHub/Provider/GitHubAuthenticatedContext.cs @@ -31,7 +31,6 @@ public GitHubAuthenticatedContext(IOwinContext context, JObject user, string acc Name = TryGetValue(user, "name"); Link = TryGetValue(user, "url"); UserName = TryGetValue(user, "login"); - Email = TryGetValue(user, "email"); } /// @@ -65,11 +64,6 @@ public GitHubAuthenticatedContext(IOwinContext context, JObject user, string acc /// public string UserName { get; private set; } - /// - /// Gets the GitHub email - /// - public string Email { get; private set; } - /// /// Gets the representing the user /// diff --git a/Owin.Security.Providers/HealthGraph/Constants.cs b/Owin.Security.Providers/HealthGraph/Constants.cs deleted file mode 100644 index 3b4b245..0000000 --- a/Owin.Security.Providers/HealthGraph/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.HealthGraph -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "HealthGraph"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationExtensions.cs b/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationExtensions.cs deleted file mode 100644 index 5942962..0000000 --- a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace Owin.Security.Providers.HealthGraph -{ - public static class HealthGraphAuthenticationExtensions - { - public static IAppBuilder UseHealthGraphAuthentication( - this IAppBuilder app, - HealthGraphAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(HealthGraphAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseHealthGraphAuthentication( - this IAppBuilder app, - string clientId, - string clientSecret) - { - return app.UseHealthGraphAuthentication(new HealthGraphAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationHandler.cs b/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationHandler.cs deleted file mode 100644 index e8b5c5c..0000000 --- a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationHandler.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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.HealthGraph.Provider; - -namespace Owin.Security.Providers.HealthGraph -{ - public class HealthGraphAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private HttpClient httpClient; - private ILogger logger; - - public HealthGraphAuthenticationHandler( - HttpClient httpClient, - ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected async override Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - 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]; - } - - 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>(); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("code", code)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - - // 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; - - // Get the RunKeeper user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken)); - HttpResponseMessage userResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - var userText = await userResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(userText); - - // Get the RunKeeper Profile - HttpRequestMessage profileRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.ProfileInfoEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken)); - HttpResponseMessage profileResponse = await httpClient.SendAsync(profileRequest, Request.CallCancelled); - profileResponse.EnsureSuccessStatusCode(); - var profileText = await profileResponse.Content.ReadAsStringAsync(); - JObject profile = JObject.Parse(profileText); - - var context = new HealthGraphAuthenticatedContext(Context, user, profile, accessToken); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - - if (!string.IsNullOrEmpty(context.UserId)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.UserId, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&response_type=code" + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new HealthGraphReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationMiddleware.cs b/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationMiddleware.cs deleted file mode 100644 index 434d47e..0000000 --- a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationMiddleware.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.HealthGraph.Provider; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.HealthGraph -{ - public class HealthGraphAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public HealthGraphAuthenticationMiddleware( - OwinMiddleware next, - IAppBuilder app, - HealthGraphAuthenticationOptions options) : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new HealthGraphAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof(HealthGraphAuthenticationMiddleware).FullName, - Options.AuthenticationType, - "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin HealthGraph middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - protected override AuthenticationHandler CreateHandler() - { - return new HealthGraphAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(HealthGraphAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } - -} diff --git a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationOptions.cs b/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationOptions.cs deleted file mode 100644 index 89d2b3d..0000000 --- a/Owin.Security.Providers/HealthGraph/HealthGraphAuthenticationOptions.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Owin.Security.Providers.HealthGraph.Provider; - -namespace Owin.Security.Providers.HealthGraph -{ - public class HealthGraphAuthenticationOptions : AuthenticationOptions - { - private const string AuthorizationEndPoint = "https://runkeeper.com/apps/authorize"; - private const string TokenEndpoint = "https://runkeeper.com/apps/token"; - private const string UserInfoEndpoint = "https://api.runkeeper.com/user"; - private const string ProfileInfoEndpoint = "https://api.runkeeper.com/profile"; - - public class HealthGraphAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request GitHub access - /// - /// - /// Defaults to https://runkeeper.com/apps/authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://api.runkeeper.com/profile - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://api.runkeeper.com/user - /// - public string UserInfoEndpoint { get; set; } - - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://api.runkeeper.com/profile - /// - public string ProfileInfoEndpoint { get; set; } - } - - public HealthGraphAuthenticationOptions() - : base(Constants.DefaultAuthenticationType) - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-healthgraph"); - AuthenticationMode = AuthenticationMode.Passive; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new HealthGraphAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint, - UserInfoEndpoint = UserInfoEndpoint, - ProfileInfoEndpoint = ProfileInfoEndpoint, - }; - } - - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - public TimeSpan BackchannelTimeout { get; set; } - - public PathString CallbackPath { get; set; } - - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - public string ClientId { get; set; } - - public string ClientSecret { get; set; } - - public PropertiesDataFormat StateDataFormat { get; set; } - - public HealthGraphAuthenticationEndpoints Endpoints { get; set; } - - public IHealthGraphAuthenticationProvider Provider { get; set; } - - public string SignInAsAuthenticationType { get; set; } - } -} diff --git a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticatedContext.cs b/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticatedContext.cs deleted file mode 100644 index bb0d941..0000000 --- a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticatedContext.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.HealthGraph.Provider -{ - public class HealthGraphAuthenticatedContext : BaseContext - { - public HealthGraphAuthenticatedContext(IOwinContext context, - JObject user, - JObject profile, - string accessToken) : base(context) - { - User = user; - Profile = profile; - AccessToken = accessToken; - - UserId = TryGetValue(user, "userID"); - Name = TryGetValue(profile, "name"); - } - - public JObject Profile { get; set; } - - public JObject User { get; set; } - - public string UserId { get; set; } - - public string Name { get; set; } - - public string AccessToken { get; set; } - - public ClaimsIdentity Identity { get; set; } - - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticationProvider.cs b/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticationProvider.cs deleted file mode 100644 index e8755e4..0000000 --- a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphAuthenticationProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.HealthGraph.Provider -{ - public class HealthGraphAuthenticationProvider : IHealthGraphAuthenticationProvider - { - public HealthGraphAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndPoint = context => Task.FromResult(null); - } - - public Func OnAuthenticated { get; set; } - - public Func OnReturnEndPoint { get; set; } - - public Task Authenticated(HealthGraphAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - public Task ReturnEndpoint(HealthGraphReturnEndpointContext context) - { - return OnReturnEndPoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphReturnEndpointContext.cs b/Owin.Security.Providers/HealthGraph/Provider/HealthGraphReturnEndpointContext.cs deleted file mode 100644 index 10da06f..0000000 --- a/Owin.Security.Providers/HealthGraph/Provider/HealthGraphReturnEndpointContext.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.HealthGraph.Provider -{ - public class HealthGraphReturnEndpointContext : ReturnEndpointContext - { - public HealthGraphReturnEndpointContext(IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/HealthGraph/Provider/IHealthGraphAuthenticationProvider.cs b/Owin.Security.Providers/HealthGraph/Provider/IHealthGraphAuthenticationProvider.cs deleted file mode 100644 index 0cfb125..0000000 --- a/Owin.Security.Providers/HealthGraph/Provider/IHealthGraphAuthenticationProvider.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; -using Owin.Security.Providers.GitHub; - -namespace Owin.Security.Providers.HealthGraph.Provider -{ - public interface IHealthGraphAuthenticationProvider - { - Task Authenticated(HealthGraphAuthenticatedContext context); - - Task ReturnEndpoint(HealthGraphReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Instagram/InstagramAuthenticationHandler.cs b/Owin.Security.Providers/Instagram/InstagramAuthenticationHandler.cs index 7493ebf..8ffc901 100644 --- a/Owin.Security.Providers/Instagram/InstagramAuthenticationHandler.cs +++ b/Owin.Security.Providers/Instagram/InstagramAuthenticationHandler.cs @@ -156,8 +156,8 @@ protected override Task ApplyResponseChallengeAsync() // OAuth2 10.12 CSRF GenerateCorrelationId(properties); - // plus separated (do not URL encode) - string scope = string.Join("+", Options.Scope); + // comma separated + string scope = string.Join(",", Options.Scope); string state = Options.StateDataFormat.Protect(properties); @@ -166,7 +166,7 @@ protected override Task ApplyResponseChallengeAsync() "?response_type=code" + "&client_id=" + Uri.EscapeDataString(Options.ClientId) + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + scope + + "&scope=" + Uri.EscapeDataString(scope) + "&state=" + Uri.EscapeDataString(state); Response.Redirect(authorizationEndpoint); diff --git a/Owin.Security.Providers/LinkedIn/LinkedInAuthenticationHandler.cs b/Owin.Security.Providers/LinkedIn/LinkedInAuthenticationHandler.cs index 8ee881b..e686f8d 100644 --- a/Owin.Security.Providers/LinkedIn/LinkedInAuthenticationHandler.cs +++ b/Owin.Security.Providers/LinkedIn/LinkedInAuthenticationHandler.cs @@ -17,7 +17,7 @@ public class LinkedInAuthenticationHandler : AuthenticationHandler diff --git a/Owin.Security.Providers/Owin.Security.Providers.csproj b/Owin.Security.Providers/Owin.Security.Providers.csproj index e99f0dd..6122545 100644 --- a/Owin.Security.Providers/Owin.Security.Providers.csproj +++ b/Owin.Security.Providers/Owin.Security.Providers.csproj @@ -11,7 +11,7 @@ Owin.Security.Providers v4.5 512 - ..\ + ..\..\..\..\AngJobs.com\src\Angjobs\ true @@ -69,23 +69,6 @@ - - - - - - - - - - - - - - - - - @@ -95,58 +78,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -164,13 +96,6 @@ - - - - - - - @@ -206,15 +131,6 @@ - - - - - - - - - True @@ -230,7 +146,6 @@ - @@ -240,24 +155,6 @@ - - - - - - - - - - - - - - - - - - @@ -271,6 +168,15 @@ + + + + + + + + + @@ -284,48 +190,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -339,15 +203,6 @@ - - - - - - - - - @@ -357,9 +212,7 @@ - - Designer - + diff --git a/Owin.Security.Providers/Owin.Security.Providers.csproj.DotSettings b/Owin.Security.Providers/Owin.Security.Providers.csproj.DotSettings index 6c10e3b..ff86f88 100644 --- a/Owin.Security.Providers/Owin.Security.Providers.csproj.DotSettings +++ b/Owin.Security.Providers/Owin.Security.Providers.csproj.DotSettings @@ -1,7 +1,3 @@  - True True - True - True - True - True \ No newline at end of file + True \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/Constants.cs b/Owin.Security.Providers/PayPal/Constants.cs deleted file mode 100644 index 6361dfc..0000000 --- a/Owin.Security.Providers/PayPal/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.PayPal -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "PayPal"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/PayPalAuthenticationExtensions.cs b/Owin.Security.Providers/PayPal/PayPalAuthenticationExtensions.cs deleted file mode 100644 index caeedbd..0000000 --- a/Owin.Security.Providers/PayPal/PayPalAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.PayPal -{ - public static class PayPalAuthenticationExtensions - { - public static IAppBuilder UsePayPalAuthentication(this IAppBuilder app, - PayPalAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(PayPalAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UsePayPalAuthentication(this IAppBuilder app, string clientId, string clientSecret, bool isSandbox=false) - { - return app.UsePayPalAuthentication(new PayPalAuthenticationOptions(isSandbox) - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/PayPalAuthenticationHandler.cs b/Owin.Security.Providers/PayPal/PayPalAuthenticationHandler.cs deleted file mode 100644 index fcc4985..0000000 --- a/Owin.Security.Providers/PayPal/PayPalAuthenticationHandler.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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 System.Text; - -namespace Owin.Security.Providers.PayPal -{ - public class PayPalAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger _logger; - private readonly HttpClient _httpClient; - - public PayPalAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this._httpClient = httpClient; - this._logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - string error = "Unknown"; - 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("error"); - if(values != null && values.Count == 1) - { - error = values[0]; - } - - values = query.GetValues("state"); - if(values != null && values.Count == 1) - { - state = values[0]; - } - - 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; - - // Request the token - var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.Endpoints.TokenEndpoint); - requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", Options.ClientId, Options.ClientSecret)))); - requestMessage.Content = new FormUrlEncodedContent(new List>{ - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("code", code), - new KeyValuePair("redirect_uri", redirectUri), - }); - var tokenResponse = await _httpClient.SendAsync(requestMessage); - tokenResponse.EnsureSuccessStatusCode(); - var text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - var response = JsonConvert.DeserializeObject(text); - var accessToken = (string)response.access_token; - var refreshToken = (string)response.refresh_token; - - // Get the PayPal user - var userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint); - userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - var userResponse = await _httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - text = await userResponse.Content.ReadAsStringAsync(); - var user = JObject.Parse(text); - - var context = new PayPalAuthenticatedContext(Context, user, accessToken, refreshToken) - { - 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.Email)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); - } - if(!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim("urn:paypal:name", context.Name, 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 + " : " + error); - } - return new AuthenticationTicket(null, properties); - } - - protected override Task ApplyResponseChallengeAsync() - { - if(Response.StatusCode != 401) - { - return Task.FromResult(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if(challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if(string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - string scope = string.Join(" ", Options.Scope); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&response_type=code" + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if(Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - AuthenticationTicket ticket = await AuthenticateAsync(); - if(ticket == null) - { - _logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new PayPalReturnEndpointContext(Context, ticket) - { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, - RedirectUri = ticket.Properties.RedirectUri - }; - - await Options.Provider.ReturnEndpoint(context); - - if(context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if(!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if(!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if(context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/PayPalAuthenticationMiddleware.cs b/Owin.Security.Providers/PayPal/PayPalAuthenticationMiddleware.cs deleted file mode 100644 index 9200e40..0000000 --- a/Owin.Security.Providers/PayPal/PayPalAuthenticationMiddleware.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.PayPal -{ - public class PayPalAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public PayPalAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - PayPalAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new PayPalAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (PayPalAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin PayPal middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new PayPalAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(PayPalAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/PayPalAuthenticationOptions.cs b/Owin.Security.Providers/PayPal/PayPalAuthenticationOptions.cs deleted file mode 100644 index f57079d..0000000 --- a/Owin.Security.Providers/PayPal/PayPalAuthenticationOptions.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.PayPal -{ - public class PayPalAuthenticationOptions : AuthenticationOptions - { - public class PayPalAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request PayPal access - /// - /// - /// Defaults to https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://api.paypal.com/v1/identity/openidconnect/tokenservice - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://api.paypal.com/v1/identity/openidconnect/userinfo/?schema=openid - /// - public string UserInfoEndpoint { get; set; } - } - - private const string AuthorizationEndPoint = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize"; - private const string TokenEndpoint = "https://api.paypal.com/v1/identity/openidconnect/tokenservice"; - private const string UserInfoEndpoint = "https://api.paypal.com/v1/identity/openidconnect/userinfo/?schema=openid"; - - private const string SandboxAuthorizationEndPoint = "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize"; - private const string SandboxTokenEndpoint = "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice"; - private const string SandboxUserInfoEndpoint = "https://api.sandbox.paypal.com/v1/identity/openidconnect/userinfo/?schema=openid"; - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to PayPal. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with PayPal. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with PayPal. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-github". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the PayPal supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the PayPal supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the PayPal Sandbox server to connect - /// - public bool IsSandbox { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against PayPal. Overriding these endpoints allows you to use PayPal Enterprise for - /// authentication. - /// - public PayPalAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IPayPalAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public PayPalAuthenticationOptions(bool isSandbox=false) - : base("PayPal") - { - IsSandbox = isSandbox; - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-paypal"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List{ - "openid" - }; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new PayPalAuthenticationEndpoints - { - AuthorizationEndpoint = isSandbox ? SandboxAuthorizationEndPoint : AuthorizationEndPoint, - TokenEndpoint = isSandbox ? SandboxTokenEndpoint : TokenEndpoint, - UserInfoEndpoint = isSandbox ? SandboxUserInfoEndpoint : UserInfoEndpoint - }; - } - } -} diff --git a/Owin.Security.Providers/PayPal/Provider/IPayPalAuthenticationProvider.cs b/Owin.Security.Providers/PayPal/Provider/IPayPalAuthenticationProvider.cs deleted file mode 100644 index a01d6d3..0000000 --- a/Owin.Security.Providers/PayPal/Provider/IPayPalAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.PayPal -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IPayPalAuthenticationProvider - { - /// - /// Invoked whenever PayPal succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(PayPalAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(PayPalReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticatedContext.cs b/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticatedContext.cs deleted file mode 100644 index 05cf1dd..0000000 --- a/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticatedContext.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.PayPal -{ - /// - /// Contains information about the login session as well as the user . - /// - public class PayPalAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// PayPal Access token - /// PayPal Refresh token - public PayPalAuthenticatedContext(IOwinContext context, JObject user, string accessToken, string refreshToken) - : base(context) - { - User = user; - AccessToken = accessToken; - RefreshToken = refreshToken; - - Id = TryGetValue(user, "user_id").Replace("https://www.paypal.com/webapps/auth/identity/user/",""); - Name = TryGetValue(user, "name"); - Email = TryGetValue(user, "email"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the PayPal user obtained from the User Info endpoint. By default this is https://api.paypal.com/user but it can be - /// overridden in the options - /// - public JObject User { get; private set; } - - /// - /// Gets the PayPal access token - /// - public string AccessToken { get; private set; } - - public string RefreshToken { get; private set; } - - /// - /// Gets the PayPal user ID - /// - public string Id { get; private set; } - - /// - /// Gets the user's name - /// - public string Name { get; private set; } - - /// - /// Gets the PayPal emails - /// - public string Email { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} diff --git a/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticationProvider.cs b/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticationProvider.cs deleted file mode 100644 index 6d907c4..0000000 --- a/Owin.Security.Providers/PayPal/Provider/PayPalAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.PayPal -{ - /// - /// Default implementation. - /// - public class PayPalAuthenticationProvider : IPayPalAuthenticationProvider - { - /// - /// Initializes a - /// - public PayPalAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever PayPal succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(PayPalAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(PayPalReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/PayPal/Provider/PayPalReturnEndpointContext.cs b/Owin.Security.Providers/PayPal/Provider/PayPalReturnEndpointContext.cs deleted file mode 100644 index 68f9772..0000000 --- a/Owin.Security.Providers/PayPal/Provider/PayPalReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.PayPal -{ - /// - /// Provides context information to middleware providers. - /// - public class PayPalReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public PayPalReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Properties/AssemblyInfo.cs b/Owin.Security.Providers/Properties/AssemblyInfo.cs index 81044de..ac2170f 100644 --- a/Owin.Security.Providers/Properties/AssemblyInfo.cs +++ b/Owin.Security.Providers/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Owin.Security.Providers")] -[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyCopyright("Copyright © 2013")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.19.0.0")] -[assembly: AssemblyFileVersion("1.19.0.0")] +[assembly: AssemblyVersion("1.9.0.0")] +[assembly: AssemblyFileVersion("1.9.0.0")] diff --git a/Owin.Security.Providers/Salesforce/Provider/SalesforceAuthenticatedContext.cs b/Owin.Security.Providers/Salesforce/Provider/SalesforceAuthenticatedContext.cs index 9473062..b4784c6 100644 --- a/Owin.Security.Providers/Salesforce/Provider/SalesforceAuthenticatedContext.cs +++ b/Owin.Security.Providers/Salesforce/Provider/SalesforceAuthenticatedContext.cs @@ -20,14 +20,12 @@ public class SalesforceAuthenticatedContext : BaseContext /// The JSON-serialized user /// Salesforce Access token /// Salesforce Refresh token - /// Salesforce instance url - public SalesforceAuthenticatedContext(IOwinContext context, JObject user, string accessToken, string refreshToken, string instanceUrl) + public SalesforceAuthenticatedContext(IOwinContext context, JObject user, string accessToken, string refreshToken) : base(context) { User = user; AccessToken = accessToken; RefreshToken = refreshToken; - InstanceUrl = instanceUrl; Id = TryGetValue(user, "id"); UserId = TryGetValue(user, "user_id"); @@ -61,11 +59,6 @@ public SalesforceAuthenticatedContext(IOwinContext context, JObject user, string /// public string RefreshToken { get; private set; } - /// - /// Gets the Salesforce instance url - /// - public string InstanceUrl { get; private set; } - /// /// Gets the Salesforce ID / User Info Endpoint /// diff --git a/Owin.Security.Providers/Salesforce/SalesforceAuthenticationHandler.cs b/Owin.Security.Providers/Salesforce/SalesforceAuthenticationHandler.cs index 3296568..7d78a5f 100644 --- a/Owin.Security.Providers/Salesforce/SalesforceAuthenticationHandler.cs +++ b/Owin.Security.Providers/Salesforce/SalesforceAuthenticationHandler.cs @@ -86,7 +86,6 @@ protected override async Task AuthenticateCoreAsync() dynamic response = JsonConvert.DeserializeObject(text); string accessToken = (string)response.access_token; string refreshToken = (string)response.refresh_token; - string instanceUrl = (string)response.instance_url; // Get the Salesforce user using the user info endpoint, which is part of the token - response.id HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, (string)response.id + "?access_token=" + Uri.EscapeDataString(accessToken)); @@ -96,7 +95,7 @@ protected override async Task AuthenticateCoreAsync() text = await userResponse.Content.ReadAsStringAsync(); JObject user = JObject.Parse(text); - var context = new SalesforceAuthenticatedContext(Context, user, accessToken, refreshToken, instanceUrl); + var context = new SalesforceAuthenticatedContext(Context, user, accessToken, refreshToken); context.Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, @@ -135,11 +134,6 @@ protected override async Task AuthenticateCoreAsync() { context.Identity.AddClaim(new Claim("urn:Salesforce:name", context.DisplayName, XmlSchemaString, Options.AuthenticationType)); } - - if (!string.IsNullOrEmpty(context.OrganizationId)) - { - context.Identity.AddClaim(new Claim("urn:Salesforce:organization_id", context.OrganizationId, XmlSchemaString, Options.AuthenticationType)); - } context.Properties = properties; @@ -264,4 +258,4 @@ private async Task InvokeReplyPathAsync() return false; } } -} +} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/Constants.cs b/Owin.Security.Providers/SoundCloud/Constants.cs deleted file mode 100644 index 9fe5154..0000000 --- a/Owin.Security.Providers/SoundCloud/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.SoundCloud -{ - public class Constants - { - public const string DefaultAuthenticationType = "SoundCloud"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/Provider/ISoundCloudAuthenticationProvider.cs b/Owin.Security.Providers/SoundCloud/Provider/ISoundCloudAuthenticationProvider.cs deleted file mode 100644 index 276a564..0000000 --- a/Owin.Security.Providers/SoundCloud/Provider/ISoundCloudAuthenticationProvider.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.SoundCloud.Provider -{ - /// - /// Specifies callback methods which the invokes to enable - /// developer control over the authentication process. /> - /// - public interface ISoundCloudAuthenticationProvider - { - /// - /// Invoked whenever SoundCloud succesfully authenticates a user - /// - /// - /// Contains information about the login session as well as the user - /// . - /// - /// A representing the completed operation. - Task Authenticated(SoundCloudAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the - /// browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(SoundCloudReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticatedContext.cs b/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticatedContext.cs deleted file mode 100644 index 1b22cfd..0000000 --- a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticatedContext.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.SoundCloud.Provider -{ - /// - /// Contains information about the login session as well as the user - /// . - /// - public class SoundCloudAuthenticatedContext : BaseContext - { - public SoundCloudAuthenticatedContext(IOwinContext context, JObject user, string accessToken) - : base(context) - { - User = user; - AccessToken = accessToken; - - Id = TryGetValue(user, "id"); - UserName = TryGetValue(user, "username"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the SoundCloud user obtained from the endpoint https://api.soundcloud.com/me - /// - public JObject User { get; private set; } - - /// - /// Gets the SoundCloud access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the SoundCloud user ID - /// - public string Id { get; set; } - - /// - /// Gets the SoundCloud username - /// - public string UserName { get; set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticationProvider.cs b/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticationProvider.cs deleted file mode 100644 index 457ccd1..0000000 --- a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudAuthenticationProvider.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.SoundCloud.Provider -{ - /// - /// Default implementation. - /// - public class SoundCloudAuthenticationProvider : ISoundCloudAuthenticationProvider - { - /// - /// Initializes a - /// - public SoundCloudAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever SoundCloud succesfully authenticates a user - /// - /// - /// Contains information about the login session as well as the user - /// . - /// - /// A representing the completed operation. - public virtual Task Authenticated(SoundCloudAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the - /// browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public Task ReturnEndpoint(SoundCloudReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudReturnEndpointContext.cs b/Owin.Security.Providers/SoundCloud/Provider/SoundCloudReturnEndpointContext.cs deleted file mode 100644 index c882e19..0000000 --- a/Owin.Security.Providers/SoundCloud/Provider/SoundCloudReturnEndpointContext.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.SoundCloud.Provider -{ - /// - /// Provides context information to middleware providers. - /// - public class SoundCloudReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// OWIN environment - /// The authentication ticket - public SoundCloudReturnEndpointContext(IOwinContext context, AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationExtensions.cs b/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationExtensions.cs deleted file mode 100644 index 3d01dac..0000000 --- a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.SoundCloud -{ - public static class SoundCloudAuthenticationExtensions - { - public static IAppBuilder UseSoundCloudAuthentication(this IAppBuilder app, - SoundCloudAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof (SoundCloudAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseSoundCloudAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseSoundCloudAuthentication(new SoundCloudAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationHandler.cs b/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationHandler.cs deleted file mode 100644 index de799d2..0000000 --- a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationHandler.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -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.SoundCloud.Provider; - -namespace Owin.Security.Providers.SoundCloud -{ - public class SoundCloudAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://api.soundcloud.com/oauth2/token"; - private const string ConnectEndpoint = "https://soundcloud.com/connect"; - private const string UserInfoEndpoint = "https://api.soundcloud.com/me.json"; - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public SoundCloudAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - try - { - string code = null; - string state = null; - - var query = Request.Query; - var 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]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - if (!ValidateCorrelationId(properties, logger)) - { - return new AuthenticationTicket(null, properties); - } - - var requestPrefix = Request.Scheme + "://" + Request.Host; - var redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - var body = new List> - { - new KeyValuePair("code", code), - new KeyValuePair("redirect_uri", redirectUri), - new KeyValuePair("client_id", Options.ClientId), - new KeyValuePair("grant_type", "authorization_code"), - new KeyValuePair("client_secret", Options.ClientSecret) - }; - - var tokenResponse = await httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); - tokenResponse.EnsureSuccessStatusCode(); - var text = await tokenResponse.Content.ReadAsStringAsync(); - - dynamic response = JsonConvert.DeserializeObject(text); - var accessToken = (string) response.access_token; - - var userRequest = new HttpRequestMessage( - HttpMethod.Get, - UserInfoEndpoint + "?oauth_token=" + Uri.EscapeDataString(accessToken)); - var userResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - text = await userResponse.Content.ReadAsStringAsync(); - var user = JObject.Parse(text); - - var context = new SoundCloudAuthenticatedContext(Context, user, accessToken) - { - 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)); - } - context.Properties = properties; - - await Options.Provider.Authenticated(context); - - return new AuthenticationTicket(context.Identity, context.Properties); - } - catch (Exception exception) - { - logger.WriteError(exception.Message); - } - return new AuthenticationTicket(null, properties); - } - - protected override Task ApplyResponseChallengeAsync() - { - if (Response.StatusCode != 401) - { - return Task.FromResult(null); - } - - var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - var baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - var currentUri = - baseUri + - Request.Path + - Request.QueryString; - - var redirectUri = - baseUri + - Options.CallbackPath; - - var properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - var state = Options.StateDataFormat.Protect(properties); - - var authorizationEndpoint = - ConnectEndpoint - + "?client_id=" + Uri.EscapeDataString(Options.ClientId) - + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) - + "&response_type=" + "code" - + "&scope=" + "non-expiring" - + "&display=" + "popup" - + "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - var ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new SoundCloudReturnEndpointContext(Context, ticket) - { - SignInAsAuthenticationType = Options.SignInAsAuthenticationType, - RedirectUri = ticket.Properties.RedirectUri - }; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && context.Identity != null) - { - var grantIdentity = context.Identity; - if (!string.Equals( - grantIdentity.AuthenticationType, - context.SignInAsAuthenticationType, - StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity( - grantIdentity.Claims, - context.SignInAsAuthenticationType, - grantIdentity.NameClaimType, - grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - var redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationMiddleware.cs b/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationMiddleware.cs deleted file mode 100644 index cbb2905..0000000 --- a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationMiddleware.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; -using Owin.Security.Providers.SoundCloud.Provider; - -namespace Owin.Security.Providers.SoundCloud -{ - public class SoundCloudAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public SoundCloudAuthenticationMiddleware( - OwinMiddleware next, - IAppBuilder app, - SoundCloudAuthenticationOptions options) : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new SoundCloudAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - var dataProtector = app.CreateDataProtector( - typeof (SoundCloudAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10 - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin SoundCloud middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - protected override AuthenticationHandler CreateHandler() - { - return new SoundCloudAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(SoundCloudAuthenticationOptions options) - { - var handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationOptions.cs b/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationOptions.cs deleted file mode 100644 index be0faca..0000000 --- a/Owin.Security.Providers/SoundCloud/SoundCloudAuthenticationOptions.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Owin.Security.Providers.SoundCloud.Provider; - -namespace Owin.Security.Providers.SoundCloud -{ - public class SoundCloudAuthenticationOptions : AuthenticationOptions - { - /// - /// Initializes a new - /// - public SoundCloudAuthenticationOptions() - : base("SoundCloud") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-soundcloud"); - AuthenticationMode = AuthenticationMode.Passive; - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to SoundCloud. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with SoundCloud. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with SoundCloud. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-soundcloud". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the SoundCloud supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the SoundCloud supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public ISoundCloudAuthenticationProvider Provider { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/Constants.cs b/Owin.Security.Providers/Spotify/Constants.cs deleted file mode 100644 index 8cfc92a..0000000 --- a/Owin.Security.Providers/Spotify/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Spotify -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Spotify"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/Provider/ISpotifyAuthenticationProvider.cs b/Owin.Security.Providers/Spotify/Provider/ISpotifyAuthenticationProvider.cs deleted file mode 100644 index 46aa68f..0000000 --- a/Owin.Security.Providers/Spotify/Provider/ISpotifyAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Spotify.Provider -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface ISpotifyAuthenticationProvider - { - /// - /// Invoked whenever Spotify succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(SpotifyAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(SpotifyReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticatedContext.cs b/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticatedContext.cs deleted file mode 100644 index 2be9efc..0000000 --- a/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticatedContext.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; -using System; -using System.Globalization; -using System.Security.Claims; - -namespace Owin.Security.Providers.Spotify.Provider -{ - public class SpotifyAuthenticatedContext: BaseContext - { - public SpotifyAuthenticatedContext(IOwinContext context, JObject user, string accessToken, string refreshToken, string expiresIn) - : base(context) - { - User = user; - AccessToken = accessToken; - RefreshToken = refreshToken; - - int expiresValue; - if (Int32.TryParse(expiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) - { - ExpiresIn = TimeSpan.FromSeconds(expiresValue); - } - - Id = TryGetValue(user, "id"); - Name = TryGetValue(user, "display_name"); - - ProfilePicture = TryGetListValue(user, "images", 0, "url"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Spotify user obtained from token ednpoint - /// - public JObject User { get; private set; } - - /// - /// Gets the Spotify access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets Spotify refresh token - /// - public string RefreshToken { get; private set; } - - /// - /// Gets Spotify access token expiration time - /// - public TimeSpan? ExpiresIn { get; set; } - - /// - /// Gets the Spotify user ID - /// - public string Id { get; private set; } - - /// - /// Gets the user's name - /// - public string Name { get; private set; } - - /// - /// Gets the Spotify users profile picture - /// - public string ProfilePicture { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - - private static string TryGetListValue(JObject user, string listPropertyName, int listPosition, string listEntryPropertyName) - { - JToken listValue; - bool valueExists = user.TryGetValue(listPropertyName, out listValue); - if (!valueExists) return null; - JArray list = (JArray)listValue; - - if (list.Count <= listPosition) return null; - JToken entry = list[listPosition]; - - return entry.Value(listEntryPropertyName); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticationProvider.cs b/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticationProvider.cs deleted file mode 100644 index e8cee09..0000000 --- a/Owin.Security.Providers/Spotify/Provider/SpotifyAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Spotify.Provider -{ - /// - /// Default implementation. - /// - public class SpotifyAuthenticationProvider : ISpotifyAuthenticationProvider - { - /// - /// Initializes a - /// - public SpotifyAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Spotify succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(SpotifyAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(SpotifyReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/SpotifyAuthenticationExtensions.cs b/Owin.Security.Providers/Spotify/SpotifyAuthenticationExtensions.cs deleted file mode 100644 index 821ebbe..0000000 --- a/Owin.Security.Providers/Spotify/SpotifyAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Spotify -{ - public static class SpotifyAuthenticationExtensions - { - public static IAppBuilder UseSpotifyAuthentication(this IAppBuilder app, - SpotifyAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(SpotifyAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseSpotifyAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseSpotifyAuthentication(new SpotifyAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/SpotifyAuthenticationHandler.cs b/Owin.Security.Providers/Spotify/SpotifyAuthenticationHandler.cs deleted file mode 100644 index cd55e04..0000000 --- a/Owin.Security.Providers/Spotify/SpotifyAuthenticationHandler.cs +++ /dev/null @@ -1,243 +0,0 @@ -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.Spotify.Provider; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Text; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Spotify -{ - public class SpotifyAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://accounts.spotify.com/api/token"; - private const string UserInfoEndpoint = "https://api.spotify.com/v1/me"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public SpotifyAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - 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]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - - // OAuth2 10.12 CSRF - if (!ValidateCorrelationId(properties, logger)) - { - return new AuthenticationTicket(null, properties); - } - - // Check for error - if (Request.Query.Get("error") != null) - 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>(); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("code", code)); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - - string secret = Options.ClientId + ":" + Options.ClientSecret; - var secretBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(secret)); - - HttpRequestMessage tokenRequest = new HttpRequestMessage(HttpMethod.Post, TokenEndpoint); - tokenRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", secretBase64); - tokenRequest.Content = new FormUrlEncodedContent(body); - - // Request the token - HttpResponseMessage tokenResponse = await httpClient.SendAsync(tokenRequest); - 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 expiresIn = (string)response.expires_in; - - // Get the Spotify user - HttpRequestMessage graphRequest = new HttpRequestMessage(HttpMethod.Get, UserInfoEndpoint); - graphRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - - HttpResponseMessage graphResponse = await httpClient.SendAsync(graphRequest, Request.CallCancelled); - graphResponse.EnsureSuccessStatusCode(); - text = await graphResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new SpotifyAuthenticatedContext(Context, user, accessToken, refreshToken, expiresIn); - 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.Name)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.ProfilePicture)) - { - context.Identity.AddClaim(new Claim("urn:spotify:profilepicture", context.ProfilePicture, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - string scope = string.Join(" ", Options.Scope); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - "https://accounts.spotify.com/authorize" + - "?response_type=code" + - "&client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new SpotifyReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/SpotifyAuthenticationMiddleware.cs b/Owin.Security.Providers/Spotify/SpotifyAuthenticationMiddleware.cs deleted file mode 100644 index acbaaa8..0000000 --- a/Owin.Security.Providers/Spotify/SpotifyAuthenticationMiddleware.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; -using Owin.Security.Providers.Spotify.Provider; -using System; -using System.Globalization; -using System.Net.Http; - -namespace Owin.Security.Providers.Spotify -{ - public class SpotifyAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public SpotifyAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - SpotifyAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new SpotifyAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof(SpotifyAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new SpotifyAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(SpotifyAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Spotify/SpotifyAuthenticationOptions.cs b/Owin.Security.Providers/Spotify/SpotifyAuthenticationOptions.cs deleted file mode 100644 index 61460d4..0000000 --- a/Owin.Security.Providers/Spotify/SpotifyAuthenticationOptions.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Owin.Security.Providers.Spotify.Provider; -using System; -using System.Collections.Generic; -using System.Net.Http; - -namespace Owin.Security.Providers.Spotify -{ - public class SpotifyAuthenticationOptions : AuthenticationOptions - { - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Spotify. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Spotify. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Spotify. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-spotify". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Spotify supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Spotify supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public ISpotifyAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public SpotifyAuthenticationOptions() - : base("Spotify") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-spotify"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List(); - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Steam/SteamAuthenticationExtensions.cs b/Owin.Security.Providers/Steam/SteamAuthenticationExtensions.cs index d3b3ba9..96328a0 100644 --- a/Owin.Security.Providers/Steam/SteamAuthenticationExtensions.cs +++ b/Owin.Security.Providers/Steam/SteamAuthenticationExtensions.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Owin; +using System; namespace Owin.Security.Providers.Steam { @@ -24,7 +25,8 @@ public static IAppBuilder UseSteamAuthentication(this IAppBuilder app, SteamAuth throw new ArgumentNullException("options"); } - return app.Use(typeof(SteamAuthenticationMiddleware), app, options); + app.Use(typeof(SteamAuthenticationMiddleware), app, options); + return app; } /// @@ -37,6 +39,10 @@ public static IAppBuilder UseSteamAuthentication(this IAppBuilder app, string ap { return UseSteamAuthentication(app, new SteamAuthenticationOptions { + ProviderDiscoveryUri = "http://steamcommunity.com/openid/", + Caption = "Steam", + AuthenticationType = "Steam", + CallbackPath = new PathString("/signin-openidsteam"), ApplicationKey = applicationKey }); } diff --git a/Owin.Security.Providers/Steam/SteamAuthenticationOptions.cs b/Owin.Security.Providers/Steam/SteamAuthenticationOptions.cs index 33849cc..080c758 100644 --- a/Owin.Security.Providers/Steam/SteamAuthenticationOptions.cs +++ b/Owin.Security.Providers/Steam/SteamAuthenticationOptions.cs @@ -1,18 +1,9 @@ -using Microsoft.Owin; -using Owin.Security.Providers.OpenID; +using Owin.Security.Providers.OpenID; namespace Owin.Security.Providers.Steam { public sealed class SteamAuthenticationOptions : OpenIDAuthenticationOptions { public string ApplicationKey { get; set; } - - public SteamAuthenticationOptions() - { - ProviderDiscoveryUri = "http://steamcommunity.com/openid/"; - Caption = "Steam"; - AuthenticationType = "Steam"; - CallbackPath = new PathString("/signin-openidsteam"); - } } } diff --git a/Owin.Security.Providers/Stripe/Constants.cs b/Owin.Security.Providers/Stripe/Constants.cs new file mode 100644 index 0000000..b4ff406 --- /dev/null +++ b/Owin.Security.Providers/Stripe/Constants.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Owin.Security.Providers.Stripe +{ + internal static class Constants + { + public const string DefaultAuthenticationType = "Stripe"; + } +} diff --git a/Owin.Security.Providers/Yammer/Provider/IYammerAuthenticationProvider.cs b/Owin.Security.Providers/Stripe/Provider/IStripeAuthenticationProvider.cs similarity index 62% rename from Owin.Security.Providers/Yammer/Provider/IYammerAuthenticationProvider.cs rename to Owin.Security.Providers/Stripe/Provider/IStripeAuthenticationProvider.cs index 00ac549..ae87c1d 100644 --- a/Owin.Security.Providers/Yammer/Provider/IYammerAuthenticationProvider.cs +++ b/Owin.Security.Providers/Stripe/Provider/IStripeAuthenticationProvider.cs @@ -1,21 +1,25 @@ -using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.Yammer.Provider +namespace Owin.Security.Providers.Stripe { - public interface IYammerAuthenticationProvider + public interface IStripeAuthenticationProvider { /// - /// Invoked whenever Yammer succesfully authenticates a user + /// Invoked whenever Stripe succesfully authenticates a user /// /// Contains information about the login session as well as the user . /// A representing the completed operation. - Task Authenticated(YammerAuthenticatedContext context); + Task Authenticated(StripeAuthenticatedContext context); /// /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. /// /// /// A representing the completed operation. - Task ReturnEndpoint(YammerReturnEndpointContext context); + Task ReturnEndpoint(StripeReturnEndpointContext context); } } diff --git a/Owin.Security.Providers/Twitch/Provider/TwitchAuthenticatedContext.cs b/Owin.Security.Providers/Stripe/Provider/StripeAuthenticatedContext.cs similarity index 50% rename from Owin.Security.Providers/Twitch/Provider/TwitchAuthenticatedContext.cs rename to Owin.Security.Providers/Stripe/Provider/StripeAuthenticatedContext.cs index 8246343..9f54998 100644 --- a/Owin.Security.Providers/Twitch/Provider/TwitchAuthenticatedContext.cs +++ b/Owin.Security.Providers/Stripe/Provider/StripeAuthenticatedContext.cs @@ -1,73 +1,88 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; +using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Provider; using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.Twitch +namespace Owin.Security.Providers.Stripe { - /// - /// Contains information about the login session as well as the user . - /// - public class TwitchAuthenticatedContext : BaseContext + public class StripeAuthenticatedContext : BaseContext { - /// - /// Initializes a + /// + /// Initializes a /// /// The OWIN environment /// The JSON-serialized user - /// Twitch Access token - public TwitchAuthenticatedContext(IOwinContext context, JObject user, string accessToken) + /// Stripe Access token + /// Seconds until expiration + public StripeAuthenticatedContext(IOwinContext context, JObject user, string accessToken, string expires, string refreshToken) : base(context) { User = user; AccessToken = accessToken; + RefreshToken = refreshToken; + int expiresValue; + if (Int32.TryParse(expires, NumberStyles.Integer, CultureInfo.InvariantCulture, out expiresValue)) + { + ExpiresIn = TimeSpan.FromSeconds(expiresValue); + } - Id = TryGetValue(user, "_id"); - Name = TryGetValue(user, "name"); - Link = TryGetValue(user, "url"); - UserName = TryGetValue(user, "name"); + /*{ + "has_mail": false, + "name": "************", + "created": 1313605620.0, + "created_utc": 1313602020.0, + "link_karma": 344, + "comment_karma": 1782, + "over_18": true, + "is_gold": false, + "is_mod": true, + "has_verified_email": true, + "id": "5omjg", + "has_mod_mail": false + }*/ + Id = TryGetValue(user, "id"); + UserName = TryGetValue(user, "display_name"); Email = TryGetValue(user, "email"); } + public string RefreshToken { get; set; } + /// /// Gets the JSON-serialized user /// /// - /// Contains the Twitch user obtained from the User Info endpoint. By default this is https://api.Twitch.com/user but it can be - /// overridden in the options + /// Contains the Stripe user /// public JObject User { get; private set; } - + /// - /// Gets the Twitch access token + /// Gets the Stripe access token /// public string AccessToken { get; private set; } /// - /// Gets the Twitch user ID + /// Gets the Stripe access token expiration time /// - public string Id { get; private set; } + public TimeSpan? ExpiresIn { get; set; } /// - /// Gets the user's name + /// Gets the Stripe user ID /// - public string Name { get; private set; } + public string Id { get; private set; } public string Link { get; private set; } /// - /// Gets the Twitch username + /// Gets the Stripe username /// public string UserName { get; private set; } - - /// - /// Gets the Twitch email - /// public string Email { get; private set; } /// diff --git a/Owin.Security.Providers/Twitch/Provider/TwitchAuthenticationProvider.cs b/Owin.Security.Providers/Stripe/Provider/StripeAuthenticationProvider.cs similarity index 66% rename from Owin.Security.Providers/Twitch/Provider/TwitchAuthenticationProvider.cs rename to Owin.Security.Providers/Stripe/Provider/StripeAuthenticationProvider.cs index 2c47fdb..df54ecc 100644 --- a/Owin.Security.Providers/Twitch/Provider/TwitchAuthenticationProvider.cs +++ b/Owin.Security.Providers/Stripe/Provider/StripeAuthenticationProvider.cs @@ -1,38 +1,34 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using System.Threading.Tasks; -namespace Owin.Security.Providers.Twitch +namespace Owin.Security.Providers.Stripe { - /// - /// Default implementation. - /// - public class TwitchAuthenticationProvider : ITwitchAuthenticationProvider + public class StripeAuthenticationProvider : IStripeAuthenticationProvider { - /// - /// Initializes a - /// - public TwitchAuthenticationProvider() + public StripeAuthenticationProvider() { OnAuthenticated = context => Task.FromResult(null); OnReturnEndpoint = context => Task.FromResult(null); } - /// /// Gets or sets the function that is invoked when the Authenticated method is invoked. /// - public Func OnAuthenticated { get; set; } + public Func OnAuthenticated { get; set; } /// /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. /// - public Func OnReturnEndpoint { get; set; } + public Func OnReturnEndpoint { get; set; } /// - /// Invoked whenever Twitch succesfully authenticates a user + /// Invoked whenever Stripe succesfully authenticates a user /// /// Contains information about the login session as well as the user . /// A representing the completed operation. - public virtual Task Authenticated(TwitchAuthenticatedContext context) + public virtual Task Authenticated(StripeAuthenticatedContext context) { return OnAuthenticated(context); } @@ -42,9 +38,9 @@ public virtual Task Authenticated(TwitchAuthenticatedContext context) /// /// /// A representing the completed operation. - public virtual Task ReturnEndpoint(TwitchReturnEndpointContext context) + public virtual Task ReturnEndpoint(StripeReturnEndpointContext context) { return OnReturnEndpoint(context); } } -} \ No newline at end of file +} diff --git a/Owin.Security.Providers/Spotify/Provider/SpotifyReturnEndpointContext.cs b/Owin.Security.Providers/Stripe/Provider/StripeReturnEndpointContext.cs similarity index 57% rename from Owin.Security.Providers/Spotify/Provider/SpotifyReturnEndpointContext.cs rename to Owin.Security.Providers/Stripe/Provider/StripeReturnEndpointContext.cs index 9ae6e0f..f463c58 100644 --- a/Owin.Security.Providers/Spotify/Provider/SpotifyReturnEndpointContext.cs +++ b/Owin.Security.Providers/Stripe/Provider/StripeReturnEndpointContext.cs @@ -1,21 +1,26 @@ using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Provider; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.Spotify.Provider +namespace Owin.Security.Providers.Stripe { - public class SpotifyReturnEndpointContext : ReturnEndpointContext + public class StripeReturnEndpointContext : ReturnEndpointContext { - /// + /// /// /// /// OWIN environment /// The authentication ticket - public SpotifyReturnEndpointContext( + public StripeReturnEndpointContext( IOwinContext context, AuthenticationTicket ticket) : base(context, ticket) { } } -} \ No newline at end of file +} diff --git a/Owin.Security.Providers/Stripe/StripeAuthenticationExtensions.cs b/Owin.Security.Providers/Stripe/StripeAuthenticationExtensions.cs new file mode 100644 index 0000000..35653a7 --- /dev/null +++ b/Owin.Security.Providers/Stripe/StripeAuthenticationExtensions.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Owin.Security.Providers.Stripe +{ + public static class StripeAuthenticationExtensions + { + public static IAppBuilder UseStripeAuthentication(this IAppBuilder app, + StripeAuthenticationOptions options) + { + if (app == null) + throw new ArgumentNullException("app"); + if (options == null) + throw new ArgumentNullException("options"); + + app.Use(typeof(StripeAuthenticationMiddleware), app, options); + + return app; + } + + public static IAppBuilder UseStripeAuthentication(this IAppBuilder app, string clientId, string clientSecret) + { + return app.UseStripeAuthentication(new StripeAuthenticationOptions + { + ClientId = clientId, + ClientSecret = clientSecret + }); + } + } +} diff --git a/Owin.Security.Providers/WordPress/WordPressAuthenticationHandler.cs b/Owin.Security.Providers/Stripe/StripeAuthenticationHandler.cs similarity index 73% rename from Owin.Security.Providers/WordPress/WordPressAuthenticationHandler.cs rename to Owin.Security.Providers/Stripe/StripeAuthenticationHandler.cs index 94dcd44..7a19424 100644 --- a/Owin.Security.Providers/WordPress/WordPressAuthenticationHandler.cs +++ b/Owin.Security.Providers/Stripe/StripeAuthenticationHandler.cs @@ -1,29 +1,34 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.Owin; +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 System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.WordPress +namespace Owin.Security.Providers.Stripe { - public class WordPressAuthenticationHandler : AuthenticationHandler + public class StripeAuthenticationHandler: AuthenticationHandler { + // + //authorize_url: https://connect.stripe.com/oauth/authorize + //access_token_url: https://connect.stripe.com/oauth/token + private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://public-api.wordpress.com/oauth2/token"; - private const string UserInfoEndpoint = "https://public-api.wordpress.com/rest/v1/me"; - private const string SiteInfoEndpoint = "https://public-api.wordpress.com/rest/v1/sites/"; + private const string TokenEndpoint = "https://connect.stripe.com/oauth/token"; + private const string UserInfoEndpoint = "https://api.stripe.com/v1/account"; private readonly ILogger logger; private readonly HttpClient httpClient; - public WordPressAuthenticationHandler(HttpClient httpClient, ILogger logger) + public StripeAuthenticationHandler(HttpClient httpClient, ILogger logger) { this.httpClient = httpClient; this.logger = logger; @@ -68,12 +73,16 @@ protected override async Task AuthenticateCoreAsync() // Build up the body for the token request var body = new List>(); body.Add(new KeyValuePair("grant_type", "authorization_code")); + body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); body.Add(new KeyValuePair("code", code)); body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); + body.Add(new KeyValuePair("state", state)); + body.Add(new KeyValuePair("scope", string.Join(",", Options.Scope))); + var request = new HttpRequestMessage(HttpMethod.Post, TokenEndpoint); + request.Content = new FormUrlEncodedContent(body); // Request the token + HttpResponseMessage tokenResponse = await httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body)); tokenResponse.EnsureSuccessStatusCode(); @@ -82,43 +91,46 @@ protected override async Task AuthenticateCoreAsync() // Deserializes the token response dynamic response = JsonConvert.DeserializeObject(text); string accessToken = (string)response.access_token; - string blogId = (string)response.blog_id; - string blogUrl = (string)response.blog_url; + string expires = (string) response.expires_in; + string refreshToken = (string) response.refresh_token; - // Get the Wordpress user + // Get the Stripe Account HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, UserInfoEndpoint); userRequest.Headers.Add("User-Agent", "OWIN OAuth Provider"); - userRequest.Headers.Add("Authorization", "BEARER " + accessToken); + userRequest.Headers.Add("Authorization", "bearer " + Uri.EscapeDataString(accessToken) + ""); HttpResponseMessage graphResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); graphResponse.EnsureSuccessStatusCode(); text = await graphResponse.Content.ReadAsStringAsync(); JObject user = JObject.Parse(text); - // Get the site details - HttpRequestMessage siteRequest = new HttpRequestMessage(HttpMethod.Get, SiteInfoEndpoint + blogId); - siteRequest.Headers.Add("User-Agent", "OWIN OAuth Provider"); - siteRequest.Headers.Add("Authorization", "BEARER " + accessToken); - HttpResponseMessage siteResponse = await httpClient.SendAsync(siteRequest, Request.CallCancelled); - siteResponse.EnsureSuccessStatusCode(); - text = await siteResponse.Content.ReadAsStringAsync(); - JObject site = JObject.Parse(text); - - var context = new WordPressAuthenticatedContext(Context, user, site, accessToken, blogId, blogUrl); + var context = new StripeAuthenticatedContext(Context, user, accessToken, expires, refreshToken); 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)); + context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.UserName, XmlSchemaString, Options.AuthenticationType)); } - if (!string.IsNullOrEmpty(context.Name)) + if (!string.IsNullOrEmpty(context.UserName)) { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); + 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)); + context.Identity.AddClaim(new Claim("urn:stripe:account:email", context.Email, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Id)) + { + context.Identity.AddClaim(new Claim("urn:stripe:account:id", context.Id, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.Link)) + { + context.Identity.AddClaim(new Claim("urn:stripe:url", context.Link, XmlSchemaString, Options.AuthenticationType)); + } + if (!string.IsNullOrEmpty(context.AccessToken)) + { + context.Identity.AddClaim(new Claim("urn:stripe:accesstoken", context.AccessToken, XmlSchemaString, Options.AuthenticationType)); } context.Properties = properties; @@ -168,14 +180,19 @@ protected override Task ApplyResponseChallengeAsync() // OAuth2 10.12 CSRF GenerateCorrelationId(properties); + // comma separated + string scope = string.Join(",", Options.Scope); + string state = Options.StateDataFormat.Protect(properties); string authorizationEndpoint = - "https://public-api.wordpress.com/oauth2/authorize" + + "https://connect.stripe.com/oauth/authorize" + "?response_type=code" + "&client_id=" + Uri.EscapeDataString(Options.ClientId) + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&state=" + Uri.EscapeDataString(state); + "&scope=" + Uri.EscapeDataString(scope) + + "&state=" + Uri.EscapeDataString(state) + + "&duration=permanent"; Response.Redirect(authorizationEndpoint); } @@ -202,7 +219,7 @@ private async Task InvokeReplyPathAsync() return true; } - var context = new WordPressReturnEndpointContext(Context, ticket); + var context = new StripeReturnEndpointContext(Context, ticket); context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; context.RedirectUri = ticket.Properties.RedirectUri; @@ -236,4 +253,4 @@ private async Task InvokeReplyPathAsync() return false; } } -} \ No newline at end of file +} diff --git a/Owin.Security.Providers/Yammer/YammerAuthenticationMiddleware.cs b/Owin.Security.Providers/Stripe/StripeAuthenticationMiddleware.cs similarity index 62% rename from Owin.Security.Providers/Yammer/YammerAuthenticationMiddleware.cs rename to Owin.Security.Providers/Stripe/StripeAuthenticationMiddleware.cs index cd5a110..d753842 100644 --- a/Owin.Security.Providers/Yammer/YammerAuthenticationMiddleware.cs +++ b/Owin.Security.Providers/Stripe/StripeAuthenticationMiddleware.cs @@ -4,35 +4,43 @@ using Microsoft.Owin.Security.DataHandler; using Microsoft.Owin.Security.DataProtection; using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Yammer.Provider; +using Owin.Security.Providers.Properties; using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Net; using System.Net.Http; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.Yammer +namespace Owin.Security.Providers.Stripe { - public class YammerAuthenticationMiddleware : AuthenticationMiddleware + public class StripeAuthenticationMiddleware : AuthenticationMiddleware { - private readonly HttpClient httpClient; + private readonly HttpClient httpClient; private readonly ILogger logger; - - public YammerAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, YammerAuthenticationOptions options) : base(next, options) + + public StripeAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, + StripeAuthenticationOptions options) + : base(next, options) { if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Option must be provided {0}", "ClientId")); + throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, + "Option must be provided {0}", "ClientId")); if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Option must be provided {0}", "ClientSecret")); + throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, + "Option must be provided {0}", "ClientSecret")); - logger = app.CreateLogger(); + logger = app.CreateLogger(); if (Options.Provider == null) - Options.Provider = new YammerAuthenticationProvider(); + Options.Provider = new StripeAuthenticationProvider(); if (Options.StateDataFormat == null) { IDataProtector dataProtector = app.CreateDataProtector( - typeof(YammerAuthenticationMiddleware).FullName, + typeof (StripeAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1"); Options.StateDataFormat = new PropertiesDataFormat(dataProtector); } @@ -43,7 +51,7 @@ public YammerAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, Yamm httpClient = new HttpClient(ResolveHttpMessageHandler()) { Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10 + MaxResponseContentBufferSize = 1024*1024*10 }; } @@ -53,11 +61,11 @@ public YammerAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, Yamm /// /// /// An configured with the - /// supplied to the constructor. + /// supplied to the constructor. /// - protected override AuthenticationHandler CreateHandler() + protected override AuthenticationHandler CreateHandler() { - return new YammerAuthenticationHandler(httpClient, logger); + return new StripeAuthenticationHandler(httpClient, logger); } private HttpClientHandler ResolveHttpMessageHandler() diff --git a/Owin.Security.Providers/Yammer/YammerAuthenticationOptions.cs b/Owin.Security.Providers/Stripe/StripeAuthenticationOptions.cs similarity index 75% rename from Owin.Security.Providers/Yammer/YammerAuthenticationOptions.cs rename to Owin.Security.Providers/Stripe/StripeAuthenticationOptions.cs index e9a10ab..7d98f6c 100644 --- a/Owin.Security.Providers/Yammer/YammerAuthenticationOptions.cs +++ b/Owin.Security.Providers/Stripe/StripeAuthenticationOptions.cs @@ -1,17 +1,19 @@ using Microsoft.Owin; using Microsoft.Owin.Security; -using Owin.Security.Providers.Yammer.Provider; using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; +using System.Text; +using System.Threading.Tasks; -namespace Owin.Security.Providers.Yammer +namespace Owin.Security.Providers.Stripe { - public class YammerAuthenticationOptions : AuthenticationOptions + public class StripeAuthenticationOptions : AuthenticationOptions { - /// + /// /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Yammer. + /// in back channel communications belong to Stripe. /// /// /// The pinned certificate validator. @@ -23,14 +25,14 @@ public class YammerAuthenticationOptions : AuthenticationOptions public ICertificateValidator BackchannelCertificateValidator { get; set; } /// - /// The HttpMessageHandler used to communicate with Yammer. + /// The HttpMessageHandler used to communicate with Stripe. /// This cannot be set at the same time as BackchannelCertificateValidator unless the value /// can be downcast to a WebRequestHandler. /// public HttpMessageHandler BackchannelHttpHandler { get; set; } /// - /// Gets or sets timeout value in milliseconds for back channel communications with Yammer. + /// Gets or sets timeout value in milliseconds for back channel communications with Stripe. /// /// /// The back channel timeout in milliseconds. @@ -40,7 +42,7 @@ public class YammerAuthenticationOptions : AuthenticationOptions /// /// The request path within the application's base path where the user-agent will be returned. /// The middleware will process this request when it arrives. - /// Default value is "/signin-Yammer". + /// Default value is "/signin-Stripe". /// public PathString CallbackPath { get; set; } @@ -54,19 +56,19 @@ public string Caption } /// - /// Gets or sets the Yammer supplied Client ID + /// Gets or sets the Stripe supplied Client ID /// public string ClientId { get; set; } /// - /// Gets or sets the Yammer supplied Client Secret + /// Gets or sets the Stripe supplied Client Secret /// public string ClientSecret { get; set; } /// - /// Gets or sets the used in the authentication events + /// Gets or sets the used in the authentication events /// - public IYammerAuthenticationProvider Provider { get; set; } + public IStripeAuthenticationProvider Provider { get; set; } /// /// A list of permissions to request. @@ -85,19 +87,18 @@ public string Caption public ISecureDataFormat StateDataFormat { get; set; } /// - /// Will only allow logins from users belonging to one of these networks. Leave blank to allow all. - /// - public string[] AcceptedNetworks { get; set; } - - /// - /// Initializes a new + /// Initializes a new /// - public YammerAuthenticationOptions() - : base("Yammer") + public StripeAuthenticationOptions() + : base("Stripe") { Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-Yammer"); + CallbackPath = new PathString("/signin-stripe"); AuthenticationMode = AuthenticationMode.Passive; + Scope = new List + { + "read_write" + }; BackchannelTimeout = TimeSpan.FromSeconds(60); } } diff --git a/Owin.Security.Providers/Twitch/Constants.cs b/Owin.Security.Providers/Twitch/Constants.cs deleted file mode 100644 index cf2ebec..0000000 --- a/Owin.Security.Providers/Twitch/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Twitch -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Twitch"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Twitch/Provider/ITwitchAuthenticationProvider.cs b/Owin.Security.Providers/Twitch/Provider/ITwitchAuthenticationProvider.cs deleted file mode 100644 index e1d1d37..0000000 --- a/Owin.Security.Providers/Twitch/Provider/ITwitchAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Twitch -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface ITwitchAuthenticationProvider - { - /// - /// Invoked whenever Twitch succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(TwitchAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(TwitchReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Twitch/Provider/TwitchReturnEndpointContext.cs b/Owin.Security.Providers/Twitch/Provider/TwitchReturnEndpointContext.cs deleted file mode 100644 index 8725442..0000000 --- a/Owin.Security.Providers/Twitch/Provider/TwitchReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Twitch -{ - /// - /// Provides context information to middleware providers. - /// - public class TwitchReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public TwitchReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Twitch/TwitchAuthenticationExtensions.cs b/Owin.Security.Providers/Twitch/TwitchAuthenticationExtensions.cs deleted file mode 100644 index aa70adc..0000000 --- a/Owin.Security.Providers/Twitch/TwitchAuthenticationExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Twitch -{ - public static class TwitchAuthenticationExtensions - { - /// - /// Login with Twitch. http://yourUrl/signin-Twitch will be used as the redirect URI - /// - /// - /// - /// - public static IAppBuilder UseTwitchAuthentication(this IAppBuilder app, - TwitchAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(TwitchAuthenticationMiddleware), app, options); - - return app; - } - /// - /// Login with Twitch. http://yourUrl/signin-Twitch will be used as the redirect URI - /// - /// - /// - /// - /// - public static IAppBuilder UseTwitchAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseTwitchAuthentication(new TwitchAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Twitch/TwitchAuthenticationHandler.cs b/Owin.Security.Providers/Twitch/TwitchAuthenticationHandler.cs deleted file mode 100644 index 2be4117..0000000 --- a/Owin.Security.Providers/Twitch/TwitchAuthenticationHandler.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Text; -using System.Threading.Tasks; -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; - -namespace Owin.Security.Providers.Twitch -{ - public class TwitchAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public TwitchAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - IList values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = string.Copy(values.First()); - } - values = query.GetValues("state"); - if (values != null && values.Count == 1) - { - state = values[0]; - } - - 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>(); - body.Add(new KeyValuePair("client_id", Options.ClientId)); - body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - body.Add(new KeyValuePair("grant_type", "authorization_code")); - body.Add(new KeyValuePair("redirect_uri", redirectUri)); - body.Add(new KeyValuePair("code", code)); - - // Request the token - var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.Endpoints.TokenEndpoint); - requestMessage.Content = new FormUrlEncodedContent(body); - requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - 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; - - // Get the Twitch user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint + "?oauth_token=" + Uri.EscapeDataString(accessToken)); - userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - HttpResponseMessage userResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - text = await userResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new TwitchAuthenticatedContext(Context, user, 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.Name)) - { - context.Identity.AddClaim(new Claim("urn:Twitch:name", context.Name, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Link)) - { - context.Identity.AddClaim(new Claim("urn:Twitch:url", context.Link, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // comma separated - string scope = string.Join(" ", Options.Scope.Distinct()); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&scope=" + Uri.EscapeDataString(scope) + - "&response_type=" + "code" + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new TwitchReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Twitch/TwitchAuthenticationMiddleware.cs b/Owin.Security.Providers/Twitch/TwitchAuthenticationMiddleware.cs deleted file mode 100644 index 5b51348..0000000 --- a/Owin.Security.Providers/Twitch/TwitchAuthenticationMiddleware.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.Twitch -{ - public class TwitchAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public TwitchAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - TwitchAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new TwitchAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (TwitchAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin Twitch middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new TwitchAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(TwitchAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Twitch/TwitchAuthenticationOptions.cs b/Owin.Security.Providers/Twitch/TwitchAuthenticationOptions.cs deleted file mode 100644 index 15dd53d..0000000 --- a/Owin.Security.Providers/Twitch/TwitchAuthenticationOptions.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.Twitch -{ - public class TwitchAuthenticationOptions : AuthenticationOptions - { - public class TwitchAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request Twitch access - /// - /// - /// Defaults to https://api.twitch.tv/kraken/oauth2/authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://api.twitch.tv/kraken/oauth2/token - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://api.twitch.tv/kraken/user - /// - public string UserInfoEndpoint { get; set; } - } - - private const string AuthorizationEndPoint = "https://api.twitch.tv/kraken/oauth2/authorize"; - private const string TokenEndpoint = "https://api.twitch.tv/kraken/oauth2/token"; - private const string UserInfoEndpoint = "https://api.twitch.tv/kraken/user"; - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Twitch. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Twitch. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Twitch. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-Twitch". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Twitch supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Twitch supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against Twitch. Overriding these endpoints allows you to use Twitch Enterprise for - /// authentication. - /// - public TwitchAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public ITwitchAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public TwitchAuthenticationOptions() - : base("Twitch") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-Twitch"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List - { - "user_read" - }; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new TwitchAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint, - UserInfoEndpoint = UserInfoEndpoint - }; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/ApiResponse.cs b/Owin.Security.Providers/Untappd/ApiResponse.cs deleted file mode 100644 index 4edaadf..0000000 --- a/Owin.Security.Providers/Untappd/ApiResponse.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Untappd -{ - - internal class ResponseRoot - { - public Meta meta { get; set; } - public Response response { get; set; } - } - - public class Meta - { - public int http_code { get; set; } - } - - public class Response - { - public string access_token { get; set; } - } - -} diff --git a/Owin.Security.Providers/Untappd/Constants.cs b/Owin.Security.Providers/Untappd/Constants.cs deleted file mode 100644 index fef3041..0000000 --- a/Owin.Security.Providers/Untappd/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.Untappd -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Untappd"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/Provider/IUntappdAuthenticationProvider.cs b/Owin.Security.Providers/Untappd/Provider/IUntappdAuthenticationProvider.cs deleted file mode 100644 index f3aab47..0000000 --- a/Owin.Security.Providers/Untappd/Provider/IUntappdAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Untappd -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IUntappdAuthenticationProvider - { - /// - /// Invoked whenever Untappd succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(UntappdAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(UntappdReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticatedContext.cs b/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticatedContext.cs deleted file mode 100644 index a40a8da..0000000 --- a/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticatedContext.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Untappd -{ - /// - /// Contains information about the login session as well as the user . - /// - public class UntappdAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Untappd Access token - public UntappdAuthenticatedContext(IOwinContext context, JObject user, string accessToken) - : base(context) - { - User = user; - AccessToken = accessToken; - - Id = user["response"]["user"]["id"].ToString(); - Name = user["response"]["user"]["first_name"].ToString() + " " + user["response"]["user"]["last_name"].ToString(); - Link = user["response"]["user"]["url"].ToString(); - UserName = user["response"]["user"]["user_name"].ToString(); - Email = user["response"]["user"]["settings"]["email_address"].ToString(); - AvatarUrl = user["response"]["user"]["user_avatar"].ToString(); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Untappd user obtained from the User Info endpoint. By default this is https://api.Untappd.com/user but it can be - /// overridden in the options - /// - public JObject User { get; private set; } - - /// - /// Gets the Untappd access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Untappd user ID - /// - public string Id { get; private set; } - - /// - /// Gets the user's name - /// - public string Name { get; private set; } - - public string Link { get; private set; } - - /// - /// Gets the Untappd username - /// - public string UserName { get; private set; } - - /// - /// Gets the Untappd email - /// - public string Email { get; private set; } - - /// - /// Gets the Untappd avatar url 100x100 - /// - public string AvatarUrl { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticationProvider.cs b/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticationProvider.cs deleted file mode 100644 index a290334..0000000 --- a/Owin.Security.Providers/Untappd/Provider/UntappdAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Untappd -{ - /// - /// Default implementation. - /// - public class UntappdAuthenticationProvider : IUntappdAuthenticationProvider - { - /// - /// Initializes a - /// - public UntappdAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Untappd succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(UntappdAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(UntappdReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/Provider/UntappdReturnEndpointContext.cs b/Owin.Security.Providers/Untappd/Provider/UntappdReturnEndpointContext.cs deleted file mode 100644 index 688d513..0000000 --- a/Owin.Security.Providers/Untappd/Provider/UntappdReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Untappd -{ - /// - /// Provides context information to middleware providers. - /// - public class UntappdReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public UntappdReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Untappd/UntappdAuthenticationExtensions.cs b/Owin.Security.Providers/Untappd/UntappdAuthenticationExtensions.cs deleted file mode 100644 index f16a748..0000000 --- a/Owin.Security.Providers/Untappd/UntappdAuthenticationExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Untappd -{ - public static class UntappdAuthenticationExtensions - { - /// - /// Login with Untappd. http://yourUrl/signin-Untappd will be used as the redirect URI - /// - /// - /// - /// - public static IAppBuilder UseUntappdAuthentication(this IAppBuilder app, - UntappdAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(UntappdAuthenticationMiddleware), app, options); - - return app; - } - /// - /// Login with Untappd. http://yourUrl/signin-Untappd will be used as the redirect URI - /// - /// - /// - /// - /// - public static IAppBuilder UseUntappdAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseUntappdAuthentication(new UntappdAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/UntappdAuthenticationHandler.cs b/Owin.Security.Providers/Untappd/UntappdAuthenticationHandler.cs deleted file mode 100644 index 4a1eb15..0000000 --- a/Owin.Security.Providers/Untappd/UntappdAuthenticationHandler.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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; - -namespace Owin.Security.Providers.Untappd -{ - public class UntappdAuthenticationHandler : AuthenticationHandler - { - private const string StateCookie = "_StateCookie"; - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public UntappdAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - try - { - string code = null; - string state = null; - - IReadableStringCollection query = Request.Query; - IList values = query.GetValues("code"); - if (values != null && values.Count == 1) - { - code = string.Copy(values.First()); - } - - // restore State from Cookie - state = Request.Cookies[StateCookie]; - 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>(); - //body.Add(new KeyValuePair("client_id", Options.ClientId)); - //body.Add(new KeyValuePair("client_secret", Options.ClientSecret)); - //body.Add(new KeyValuePair("redirect_url", redirectUri)); - //body.Add(new KeyValuePair("response_type", "code")); - //body.Add(new KeyValuePair("code", code)); - - // Request the token - var requestMessage = new HttpRequestMessage(HttpMethod.Get, - String.Format(@"{0}/?client_id={1}&client_secret={2}&response_type=code&redirect_url={3}&code={4}", Options.Endpoints.TokenEndpoint, Options.ClientId, Options.ClientSecret, redirectUri, code)); - requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - HttpResponseMessage tokenResponse = await httpClient.SendAsync(requestMessage); - tokenResponse.EnsureSuccessStatusCode(); - string text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - var response = JsonConvert.DeserializeObject(text); - string accessToken = response.response.access_token; - - // Get the Untappd user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken)); - userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - HttpResponseMessage userResponse = await httpClient.SendAsync(userRequest, Request.CallCancelled); - userResponse.EnsureSuccessStatusCode(); - text = await userResponse.Content.ReadAsStringAsync(); - JObject user = JObject.Parse(text); - - var context = new UntappdAuthenticatedContext(Context, user, accessToken); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - - // Add access_token to Claims to be used later on authenticated Untappd API requests - context.Identity.AddClaim(new Claim("UntappdAccessToken", accessToken)); - - 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.Name)) - { - context.Identity.AddClaim(new Claim("urn:Untappd:name", context.Name, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Link)) - { - context.Identity.AddClaim(new Claim("urn:Untappd:url", context.Link, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.AvatarUrl)) - { - context.Identity.AddClaim(new Claim("urn:Untappd:avatar", context.AvatarUrl, XmlSchemaString, Options.AuthenticationType)); - } - - //IDictionary data = new Dictionary - // { - // { "userData", "Data" } - // }; - //properties = new AuthenticationProperties(data); - - 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_url=" + Uri.EscapeDataString(redirectUri) + - "&response_type=" + "code"; - - var cookieOptions = new CookieOptions - { - HttpOnly = true, - Secure = Request.IsSecure - }; - - Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(properties), cookieOptions); - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new UntappdReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/UntappdAuthenticationMiddleware.cs b/Owin.Security.Providers/Untappd/UntappdAuthenticationMiddleware.cs deleted file mode 100644 index eb9d6c8..0000000 --- a/Owin.Security.Providers/Untappd/UntappdAuthenticationMiddleware.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.Untappd -{ - public class UntappdAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public UntappdAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - UntappdAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new UntappdAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof(UntappdAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024 * 1024 * 10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin Untappd middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new UntappdAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(UntappdAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator == null) return handler; - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Untappd/UntappdAuthenticationOptions.cs b/Owin.Security.Providers/Untappd/UntappdAuthenticationOptions.cs deleted file mode 100644 index 43cc055..0000000 --- a/Owin.Security.Providers/Untappd/UntappdAuthenticationOptions.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.Untappd -{ - public class UntappdAuthenticationOptions : AuthenticationOptions - { - public class UntappdAuthenticationEndpoints - { - /// - /// Endpoint which is used to redirect users to request Untappd access - /// - /// - /// Defaults to https://untappd.com/oauth/authenticate/ - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://untappd.com/oauth/authorize - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults tohttps://untappd.com/v4/user/info - /// - public string UserInfoEndpoint { get; set; } - } - - private const string AuthorizationEndPoint = "https://untappd.com/oauth/authenticate"; - private const string TokenEndpoint = "https://untappd.com/oauth/authorize"; - private const string UserInfoEndpoint = "https://api.untappd.com/v4/user/info"; - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Untappd. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Untappd. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Untappd. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-Untappd". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Untappd supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the Untappd supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against Untappd. Overriding these endpoints allows you to use Untappd Enterprise for - /// authentication. - /// - public UntappdAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IUntappdAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public UntappdAuthenticationOptions() - : base("Untappd") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-untappd"); - AuthenticationMode = AuthenticationMode.Passive; - //untappd has no scopes AFAIK - Scope = new List{}; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new UntappdAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint, - UserInfoEndpoint = UserInfoEndpoint - }; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/VisualStudio/Constants.cs b/Owin.Security.Providers/VisualStudio/Constants.cs deleted file mode 100644 index 9d32b17..0000000 --- a/Owin.Security.Providers/VisualStudio/Constants.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.VisualStudio { - internal static class Constants { - public const string DefaultAuthenticationType = "Visual Studio Online"; - } -} diff --git a/Owin.Security.Providers/VisualStudio/Provider/IVisualStudioAuthenticationProvider.cs b/Owin.Security.Providers/VisualStudio/Provider/IVisualStudioAuthenticationProvider.cs deleted file mode 100644 index 2ea50b3..0000000 --- a/Owin.Security.Providers/VisualStudio/Provider/IVisualStudioAuthenticationProvider.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.VisualStudio { - - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IVisualStudioAuthenticationProvider { - /// - /// Invoked whenever Visual Studio Online succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(VisualStudioAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(VisualStudioReturnEndpointContext context); - } -} diff --git a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticatedContext.cs b/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticatedContext.cs deleted file mode 100644 index 41ba043..0000000 --- a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticatedContext.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.VisualStudio { - - /// - /// Contains information about the login session as well as the user . - /// - public class VisualStudioAuthenticatedContext : BaseContext{ - - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Visual Studio Online Access token - public VisualStudioAuthenticatedContext(IOwinContext context, JObject user, string accessToken, int expiresIn, string refreshToken) - : base(context) - { - AccessToken = accessToken; - User = user; - RefreshToken = refreshToken; - ExpiresIn = TimeSpan.FromSeconds(expiresIn); - - Id = TryGetValue(user, "id"); - Name = TryGetValue(user, "displayName"); - Email = TryGetValue(user, "emailAddress"); - Alias = TryGetValue(user, "publicAlias"); - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Visual Studio user obtained from the endpoint https://app.vssps.visualstudio.com/_apis/profile/profiles/me - /// - public JObject User { get; private set; } - - /// - /// Gets the Visual Studio Online OAuth access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Google OAuth refresh token. This is only available when the RequestOfflineAccess property of is set to true - /// - public string RefreshToken { get; private set; } - - /// - /// Gets the Google+ access token expiration time - /// - public TimeSpan? ExpiresIn { get; set; } - - /// - /// Get the user's id - /// - public string Id { get; private set; } - - /// - /// Get the user's displayName - /// - public string Name { get; private set; } - - /// - /// Get the user's email - /// - public string Email { get; private set; } - - /// - /// Get the user's publicAlias - /// - public string Alias { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticationProvider.cs b/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticationProvider.cs deleted file mode 100644 index 43af752..0000000 --- a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticationProvider.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.VisualStudio { - - /// - /// Default implementation. - /// - public class VisualStudioAuthenticationProvider : IVisualStudioAuthenticationProvider { - /// - /// Initializes a - /// - public VisualStudioAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Visual Studio Online succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(VisualStudioAuthenticatedContext context) { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(VisualStudioReturnEndpointContext context) { - return OnReturnEndpoint(context); - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioReturnEndpointContext.cs b/Owin.Security.Providers/VisualStudio/Provider/VisualStudioReturnEndpointContext.cs deleted file mode 100644 index b18d13a..0000000 --- a/Owin.Security.Providers/VisualStudio/Provider/VisualStudioReturnEndpointContext.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.VisualStudio { - - /// - /// Provides context information to middleware providers. - /// - public class VisualStudioReturnEndpointContext : ReturnEndpointContext { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public VisualStudioReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationExtensions.cs b/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationExtensions.cs deleted file mode 100644 index 9b79a17..0000000 --- a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Owin.Security.Providers.VisualStudio { - public static class VisualStudioAuthenticationExtensions { - public static IAppBuilder UseVisualStudioAuthentication(this IAppBuilder app, VisualStudioAuthenticationOptions options) { - if (app == null) throw new ArgumentNullException("app"); - if (options == null) throw new ArgumentNullException("options"); - - app.Use(typeof(VisualStudioAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseVisualStudioAuthentication(this IAppBuilder app, string appId, string appSecret) { - return app.UseVisualStudioAuthentication(new VisualStudioAuthenticationOptions { - AppId = appId, - AppSecret = appSecret - }); - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationHandler.cs b/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationHandler.cs deleted file mode 100644 index 94f44d3..0000000 --- a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationHandler.cs +++ /dev/null @@ -1,211 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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; - -namespace Owin.Security.Providers.VisualStudio { - public class VisualStudioAuthenticationHandler : AuthenticationHandler { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public VisualStudioAuthenticationHandler(HttpClient httpClient, ILogger logger) { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() { - AuthenticationProperties properties = null; - - 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]; - } - - 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 = "https://" + Request.Host; // Schema must be HTTPS - string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; - - // Build up the body for the token request - var body = new List>(); - body.Add(new KeyValuePair("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer")); - body.Add(new KeyValuePair("client_assertion", Options.AppSecret)); - body.Add(new KeyValuePair("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")); - body.Add(new KeyValuePair("assertion", code)); - body.Add(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; - int expiresIn = (int)response.expires_in; - - // Get the Visual Studio Online user - HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, Options.Endpoints.UserInfoEndpoint); - 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(); - JObject user = JObject.Parse(text); - - var context = new VisualStudioAuthenticatedContext(Context, user, accessToken, expiresIn, refreshToken); - 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.Name)) { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Email)) { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Alias)) { - context.Identity.AddClaim(new Claim("urn:vso:alias", context.Alias, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) { - string baseUri = - "https" + //Schema must be HTTPS - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - // space separated - string scope = string.Join(" ", Options.Scope); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - Options.Endpoints.AuthorizationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.AppId) + - "&response_type=Assertion" + - "&state=" + Uri.EscapeDataString(state) + - "&scope=" + Uri.EscapeDataString(scope) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new VisualStudioReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) { - string redirectUri = context.RedirectUri; - if (context.Identity == null) { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationMiddleware.cs b/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationMiddleware.cs deleted file mode 100644 index b94fde1..0000000 --- a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationMiddleware.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.VisualStudio { - public class VisualStudioAuthenticationMiddleware : AuthenticationMiddleware { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public VisualStudioAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, VisualStudioAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.AppId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.AppSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new VisualStudioAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (VisualStudioAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10, - }; - httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin VisualStudio middleware"); - httpClient.DefaultRequestHeaders.ExpectContinue = false; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() { - return new VisualStudioAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(VisualStudioAuthenticationOptions options) { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} diff --git a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationOptions.cs b/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationOptions.cs deleted file mode 100644 index c7390c8..0000000 --- a/Owin.Security.Providers/VisualStudio/VisualStudioAuthenticationOptions.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.VisualStudio { - public class VisualStudioAuthenticationOptions : AuthenticationOptions { - public class VisualStudioAuthenticationEndpoints { - /// - /// Endpoint which is used to redirect users to request Visual Studio Online access - /// - /// - /// Defaults to https://app.vssps.visualstudio.com/oauth2/authorize - /// - public string AuthorizationEndpoint { get; set; } - - /// - /// Endpoint which is used to exchange code for access token - /// - /// - /// Defaults to https://app.vssps.visualstudio.com/oauth2/token - /// - public string TokenEndpoint { get; set; } - - /// - /// Endpoint which is used to obtain user information after authentication - /// - /// - /// Defaults to https://app.vssps.visualstudio.com/_apis/profile/profiles/me - /// - public string UserInfoEndpoint { get; set; } - } - - private const string AuthorizationEndPoint = "https://app.vssps.visualstudio.com/oauth2/authorize"; - private const string TokenEndpoint = "https://app.vssps.visualstudio.com/oauth2/token"; - private const string UserInfoEndpoint = "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0"; - - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to Visual Studio Online. - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with Visual Studio Online. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with Visual Studio Online. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-visualstudio". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the Visual Studio Online supplied Application Id - /// - public string AppId { get; set; } - - /// - /// Gets or sets the Visual Studio Online supplied Application Secret - /// - public string AppSecret { get; set; } - - /// - /// Gets the sets of OAuth endpoints used to authenticate against Visual Studio. - /// authentication. - /// - public VisualStudioAuthenticationEndpoints Endpoints { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IVisualStudioAuthenticationProvider Provider { get; set; } - - /// - /// A list of permissions to request. - /// - public IList Scope { get; private set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public VisualStudioAuthenticationOptions() - : base(Constants.DefaultAuthenticationType) - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-visualstudio"); - AuthenticationMode = AuthenticationMode.Passive; - Scope = new List - { - "vso.profile" - }; - BackchannelTimeout = TimeSpan.FromSeconds(60); - Endpoints = new VisualStudioAuthenticationEndpoints - { - AuthorizationEndpoint = AuthorizationEndPoint, - TokenEndpoint = TokenEndpoint, - UserInfoEndpoint = UserInfoEndpoint - }; - } - } -} diff --git a/Owin.Security.Providers/Wargaming/Constants.cs b/Owin.Security.Providers/Wargaming/Constants.cs deleted file mode 100644 index a2fc304..0000000 --- a/Owin.Security.Providers/Wargaming/Constants.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -namespace Owin.Security.Providers.Wargaming -{ - internal static class Constants - { - internal const string DefaultAuthenticationType = "Wargaming"; - - internal const string ProviderDiscoveryUriNorthAmerica = "https://na.wargaming.net/id/openid/"; - internal const string ProviderDiscoveryUriEurope = "https://eu.wargaming.net/id/openid/"; - internal const string ProviderDiscoveryUriRussia = "https://ru.wargaming.net/id/openid/"; - internal const string ProviderDiscoveryUriAsia = "https://asia.wargaming.net/id/openid/"; - internal const string ProviderDiscoveryUriKorea = "https://kr.wargaming.net/id/openid/"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Wargaming/WargamingAccountAuthenticationExtensions.cs b/Owin.Security.Providers/Wargaming/WargamingAccountAuthenticationExtensions.cs deleted file mode 100644 index 02b9403..0000000 --- a/Owin.Security.Providers/Wargaming/WargamingAccountAuthenticationExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using Microsoft.Owin; - -namespace Owin.Security.Providers.Wargaming -{ - /// - /// Extension methods for using - /// - public static class WargamingAccountAuthenticationExtensions - { - private static string ResolveRegionDiscoveryUri(WargamingAuthenticationOptions.Region region) - { - switch (region) - { - case WargamingAuthenticationOptions.Region.NorthAmerica: - return Constants.ProviderDiscoveryUriNorthAmerica; - case WargamingAuthenticationOptions.Region.Europe: - return Constants.ProviderDiscoveryUriEurope; - case WargamingAuthenticationOptions.Region.Russia: - return Constants.ProviderDiscoveryUriRussia; - case WargamingAuthenticationOptions.Region.Asia: - return Constants.ProviderDiscoveryUriAsia; - case WargamingAuthenticationOptions.Region.Korea: - return Constants.ProviderDiscoveryUriKorea; - default: - return Constants.ProviderDiscoveryUriNorthAmerica; - } - } - - /// - /// Authenticate users using Wargaming - /// - /// The passed to the configuration method - /// Middleware configuration options - /// The updated - public static IAppBuilder UseWargamingAccountAuthentication(this IAppBuilder app, WargamingAuthenticationOptions options) - { - if (app == null) - { - throw new ArgumentNullException("app"); - } - if (options == null) - { - throw new ArgumentNullException("options"); - } - - return app.Use(typeof (WargamingAuthenticationMiddleware), app, options); - } - - /// - /// Authenticate users using Steam - /// - /// The passed to the configuration method - /// The wargaming application ID - /// The to authenticate - /// The updated - public static IAppBuilder UseWargamingAccountAuthentication(this IAppBuilder app, string appId, WargamingAuthenticationOptions.Region region = WargamingAuthenticationOptions.Region.NorthAmerica) - { - return UseWargamingAccountAuthentication(app, new WargamingAuthenticationOptions - { - ProviderDiscoveryUri = ResolveRegionDiscoveryUri(region), - Caption = "Wargaming", - AuthenticationType = "Wargaming", - CallbackPath = new PathString("/signin-wargaming"), - AppId = appId - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Wargaming/WargamingAuthenticationHandler.cs b/Owin.Security.Providers/Wargaming/WargamingAuthenticationHandler.cs deleted file mode 100644 index 8bb5477..0000000 --- a/Owin.Security.Providers/Wargaming/WargamingAuthenticationHandler.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.Owin.Logging; -using Newtonsoft.Json; -using Owin.Security.Providers.OpenID; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Claims; -using System.Text.RegularExpressions; - -namespace Owin.Security.Providers.Wargaming -{ - internal sealed class WargamingAuthenticationHandler : OpenIDAuthenticationHandlerBase - { - private readonly Regex AccountIDRegex = new Regex(@"^https://na.wargaming.net/id/([0-9]{10}).*$", RegexOptions.Compiled); - - private const string UserInfoUri = "https://api.worldoftanks.com/wot/account/info/?application_id={0}&account_id={1}&fields=nickname"; - - public WargamingAuthenticationHandler(HttpClient httpClient, ILogger logger) - : base(httpClient, logger) - { - } - - protected override void SetIdentityInformations(ClaimsIdentity identity, string claimedID, IDictionary attributeExchangeProperties) - { - Match accountIDMatch = AccountIDRegex.Match(claimedID); - if (accountIDMatch.Success) - { - string accountID = accountIDMatch.Groups[1].Value; - var getUserInfoTask = _httpClient.GetStringAsync(string.Format(UserInfoUri, Options.AppId, accountID)); - getUserInfoTask.Wait(); - string userInfoRaw = getUserInfoTask.Result; - dynamic userInfo = JsonConvert.DeserializeObject(userInfoRaw); - identity.AddClaim(new Claim(ClaimTypes.Name, (string)userInfo["data"][accountID].nickname, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType)); - } - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Wargaming/WargamingAuthenticationMiddleware.cs b/Owin.Security.Providers/Wargaming/WargamingAuthenticationMiddleware.cs deleted file mode 100644 index 3f541e3..0000000 --- a/Owin.Security.Providers/Wargaming/WargamingAuthenticationMiddleware.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.OpenID; - -namespace Owin.Security.Providers.Wargaming -{ - /// - /// OWIN middleware for authenticating users using an OpenID provider - /// - public class WargamingAuthenticationMiddleware : OpenIDAuthenticationMiddlewareBase - { - - /// - /// Initializes a - /// - /// The next middleware in the OWIN pipeline to invoke - /// The OWIN application - /// Configuration options for the middleware - public WargamingAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, WargamingAuthenticationOptions options) - : base(next, app, options) - { } - - protected override AuthenticationHandler CreateSpecificHandler() - { - return new WargamingAuthenticationHandler(_httpClient, _logger); - } - } -} diff --git a/Owin.Security.Providers/Wargaming/WargamingAuthenticationOptions.cs b/Owin.Security.Providers/Wargaming/WargamingAuthenticationOptions.cs deleted file mode 100644 index be1a2a7..0000000 --- a/Owin.Security.Providers/Wargaming/WargamingAuthenticationOptions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Owin.Security.Providers.OpenID; - -namespace Owin.Security.Providers.Wargaming -{ - public class WargamingAuthenticationOptions : OpenIDAuthenticationOptions - { - /// - /// Region to use for to log in - /// - public enum Region - { - NorthAmerica, - Europe, - Russia, - Asia, - Korea - } - - /// - /// Gets or sets the Wargaming-assigned appId - /// - public string AppId { get; set; } - } - - -} diff --git a/Owin.Security.Providers/WordPress/Constants.cs b/Owin.Security.Providers/WordPress/Constants.cs deleted file mode 100644 index 21d849c..0000000 --- a/Owin.Security.Providers/WordPress/Constants.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Owin.Security.Providers.WordPress -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "WordPress"; - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/WordPress/Provider/IWordPressAuthenticationProvider.cs b/Owin.Security.Providers/WordPress/Provider/IWordPressAuthenticationProvider.cs deleted file mode 100644 index d04ae07..0000000 --- a/Owin.Security.Providers/WordPress/Provider/IWordPressAuthenticationProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; - -namespace Owin.Security.Providers.WordPress -{ - /// - /// Specifies callback methods which the invokes to enable developer control over the authentication process. /> - /// - public interface IWordPressAuthenticationProvider - { - /// - /// Invoked whenever WordPress succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - Task Authenticated(WordPressAuthenticatedContext context); - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - Task ReturnEndpoint(WordPressReturnEndpointContext context); - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticatedContext.cs b/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticatedContext.cs deleted file mode 100644 index 22a0b4c..0000000 --- a/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticatedContext.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.WordPress -{ - /// - /// Contains information about the login session as well as the user . - /// - public class WordPressAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// WordPress Access token - /// The ID for this blog - /// The URL for this blog - public WordPressAuthenticatedContext(IOwinContext context, JObject user, JObject site, string accessToken, string blogId, string blogUrl) - : base(context) - { - User = user; - Site = site; - AccessToken = accessToken; - BlogId = blogId; - BlogUrl = blogUrl; - BlogName = TryGetValue(site, "name"); - - Id = TryGetValue(user, "ID"); - Name = TryGetValue(user, "display_name"); - Email = TryGetValue(user, "email"); - } - - /// - /// The email address of the user - /// - public string Email { get; private set; } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the WordPress user obtained from the endpoint https://public-api.wordpress.com/rest/v1/me - /// - public JObject User { get; private set; } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the WordPress user obtained from the endpoint https://public-api.wordpress.com/rest/v1/sites/{siteId} - /// - public JObject Site { get; private set; } - /// - /// Gets the WordPress OAuth access token - /// - public string AccessToken { get; private set; } - - /// - /// The ID for the blog against which the user was authenticated - /// - public string BlogId { get; private set; } - - /// - /// The URL for the blog against which the user was authenticated - /// - public string BlogUrl { get; private set; } - - /// - /// The name of the blog for the token - /// - public string BlogName { get; set; } - - /// - /// Gets the WordPress access token expiration time - /// - public TimeSpan? ExpiresIn { get; set; } - - /// - /// Gets the WordPress user ID - /// - public string Id { get; private set; } - - /// - /// The name of the user - /// - public string Name { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - - private static string TryGetValue(JObject user, string propertyName) - { - JToken value; - return user.TryGetValue(propertyName, out value) ? value.ToString() : null; - } - } -} diff --git a/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticationProvider.cs b/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticationProvider.cs deleted file mode 100644 index 175f861..0000000 --- a/Owin.Security.Providers/WordPress/Provider/WordPressAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.WordPress -{ - /// - /// Default implementation. - /// - public class WordPressAuthenticationProvider : IWordPressAuthenticationProvider - { - /// - /// Initializes a - /// - public WordPressAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever WordPress succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(WordPressAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(WordPressReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/WordPress/Provider/WordPressReturnEndpointContext.cs b/Owin.Security.Providers/WordPress/Provider/WordPressReturnEndpointContext.cs deleted file mode 100644 index 51216c9..0000000 --- a/Owin.Security.Providers/WordPress/Provider/WordPressReturnEndpointContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.WordPress -{ - /// - /// Provides context information to middleware providers. - /// - public class WordPressReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public WordPressReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/WordPress/WordPressAuthenticationExtensions.cs b/Owin.Security.Providers/WordPress/WordPressAuthenticationExtensions.cs deleted file mode 100644 index 85f4f13..0000000 --- a/Owin.Security.Providers/WordPress/WordPressAuthenticationExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace Owin.Security.Providers.WordPress -{ - public static class WordPressAuthenticationExtensions - { - public static IAppBuilder UseWordPressAuthentication(this IAppBuilder app, - WordPressAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(WordPressAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseWordPressAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseWordPressAuthentication(new WordPressAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/WordPress/WordPressAuthenticationMiddleware.cs b/Owin.Security.Providers/WordPress/WordPressAuthenticationMiddleware.cs deleted file mode 100644 index a891329..0000000 --- a/Owin.Security.Providers/WordPress/WordPressAuthenticationMiddleware.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Globalization; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.DataHandler; -using Microsoft.Owin.Security.DataProtection; -using Microsoft.Owin.Security.Infrastructure; -using Owin.Security.Providers.Properties; - -namespace Owin.Security.Providers.WordPress -{ - public class WordPressAuthenticationMiddleware : AuthenticationMiddleware - { - private readonly HttpClient httpClient; - private readonly ILogger logger; - - public WordPressAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, - WordPressAuthenticationOptions options) - : base(next, options) - { - if (String.IsNullOrWhiteSpace(Options.ClientId)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientId")); - if (String.IsNullOrWhiteSpace(Options.ClientSecret)) - throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, - Resources.Exception_OptionMustBeProvided, "ClientSecret")); - - logger = app.CreateLogger(); - - if (Options.Provider == null) - Options.Provider = new WordPressAuthenticationProvider(); - - if (Options.StateDataFormat == null) - { - IDataProtector dataProtector = app.CreateDataProtector( - typeof (WordPressAuthenticationMiddleware).FullName, - Options.AuthenticationType, "v1"); - Options.StateDataFormat = new PropertiesDataFormat(dataProtector); - } - - if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType)) - Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(); - - httpClient = new HttpClient(ResolveHttpMessageHandler(Options)) - { - Timeout = Options.BackchannelTimeout, - MaxResponseContentBufferSize = 1024*1024*10 - }; - } - - /// - /// Provides the object for processing - /// authentication-related requests. - /// - /// - /// An configured with the - /// supplied to the constructor. - /// - protected override AuthenticationHandler CreateHandler() - { - return new WordPressAuthenticationHandler(httpClient, logger); - } - - private HttpMessageHandler ResolveHttpMessageHandler(WordPressAuthenticationOptions options) - { - HttpMessageHandler handler = options.BackchannelHttpHandler ?? new WebRequestHandler(); - - // If they provided a validator, apply it or fail. - if (options.BackchannelCertificateValidator != null) - { - // Set the cert validate callback - var webRequestHandler = handler as WebRequestHandler; - if (webRequestHandler == null) - { - throw new InvalidOperationException(Resources.Exception_ValidatorHandlerMismatch); - } - webRequestHandler.ServerCertificateValidationCallback = options.BackchannelCertificateValidator.Validate; - } - - return handler; - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/WordPress/WordPressAuthenticationOptions.cs b/Owin.Security.Providers/WordPress/WordPressAuthenticationOptions.cs deleted file mode 100644 index be1fe8f..0000000 --- a/Owin.Security.Providers/WordPress/WordPressAuthenticationOptions.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Net.Http; -using Microsoft.Owin; -using Microsoft.Owin.Security; - -namespace Owin.Security.Providers.WordPress -{ - public class WordPressAuthenticationOptions : AuthenticationOptions - { - /// - /// Gets or sets the a pinned certificate validator to use to validate the endpoints used - /// in back channel communications belong to WordPress - /// - /// - /// The pinned certificate validator. - /// - /// - /// If this property is null then the default certificate checks are performed, - /// validating the subject name and if the signing chain is a trusted party. - /// - public ICertificateValidator BackchannelCertificateValidator { get; set; } - - /// - /// The HttpMessageHandler used to communicate with WordPress. - /// This cannot be set at the same time as BackchannelCertificateValidator unless the value - /// can be downcast to a WebRequestHandler. - /// - public HttpMessageHandler BackchannelHttpHandler { get; set; } - - /// - /// Gets or sets timeout value in milliseconds for back channel communications with WordPress. - /// - /// - /// The back channel timeout in milliseconds. - /// - public TimeSpan BackchannelTimeout { get; set; } - - /// - /// The request path within the application's base path where the user-agent will be returned. - /// The middleware will process this request when it arrives. - /// Default value is "/signin-wordpress". - /// - public PathString CallbackPath { get; set; } - - /// - /// Get or sets the text that the user can display on a sign in user interface. - /// - public string Caption - { - get { return Description.Caption; } - set { Description.Caption = value; } - } - - /// - /// Gets or sets the WordPress supplied Client ID - /// - public string ClientId { get; set; } - - /// - /// Gets or sets the WordPress supplied Client Secret - /// - public string ClientSecret { get; set; } - - /// - /// Gets or sets the used in the authentication events - /// - public IWordPressAuthenticationProvider Provider { get; set; } - - /// - /// Gets or sets the name of another authentication middleware which will be responsible for actually issuing a user - /// . - /// - public string SignInAsAuthenticationType { get; set; } - - /// - /// Gets or sets the type used to secure data handled by the middleware. - /// - public ISecureDataFormat StateDataFormat { get; set; } - - /// - /// Initializes a new - /// - public WordPressAuthenticationOptions() - : base("WordPress") - { - Caption = Constants.DefaultAuthenticationType; - CallbackPath = new PathString("/signin-wordpress"); - AuthenticationMode = AuthenticationMode.Passive; - BackchannelTimeout = TimeSpan.FromSeconds(60); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Yammer/Constants.cs b/Owin.Security.Providers/Yammer/Constants.cs deleted file mode 100644 index bbdfb29..0000000 --- a/Owin.Security.Providers/Yammer/Constants.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace Owin.Security.Providers.Yammer -{ - internal static class Constants - { - public const string DefaultAuthenticationType = "Yammer"; - } -} diff --git a/Owin.Security.Providers/Yammer/Provider/YammerAuthenticatedContext.cs b/Owin.Security.Providers/Yammer/Provider/YammerAuthenticatedContext.cs deleted file mode 100644 index 508962b..0000000 --- a/Owin.Security.Providers/Yammer/Provider/YammerAuthenticatedContext.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Globalization; -using System.Security.Claims; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; -using Newtonsoft.Json.Linq; - -namespace Owin.Security.Providers.Yammer.Provider -{ - /// - /// Contains information about the login session as well as the user . - /// - public class YammerAuthenticatedContext : BaseContext - { - /// - /// Initializes a - /// - /// The OWIN environment - /// The JSON-serialized user - /// Yammer Access token - public YammerAuthenticatedContext(IOwinContext context, dynamic user, string accessToken) : base(context) - { - User = user; - AccessToken = accessToken; - Id = user.id; - Name = user.full_name; - Url = user.url; - Network = user.network_name; - if (user.contact.email_addresses != null) - { - foreach (var eml in user.contact.email_addresses) - { - if (eml.type == "primary") PrimaryEmail = eml.address; - } - } - } - - /// - /// Gets the JSON-serialized user - /// - /// - /// Contains the Yammer user - /// - public dynamic User { get; private set; } - - /// - /// Gets the Yammer access token - /// - public string AccessToken { get; private set; } - - /// - /// Gets the Yammer user ID - /// - public string Id { get; private set; } - - /// - /// Gets the Yammer full_name - /// - public string Name { get; private set; } - - /// - /// Gets the Yammer url - /// - public string Url { get; private set; } - - /// - /// Gets the Yammer Primary Email - /// - public string PrimaryEmail { get; private set; } - - /// - /// Gets the yammer network_name - /// - public string Network { get; private set; } - - /// - /// Gets the representing the user - /// - public ClaimsIdentity Identity { get; set; } - - /// - /// Gets or sets a property bag for common authentication properties - /// - public AuthenticationProperties Properties { get; set; } - } -} diff --git a/Owin.Security.Providers/Yammer/Provider/YammerAuthenticationProvider.cs b/Owin.Security.Providers/Yammer/Provider/YammerAuthenticationProvider.cs deleted file mode 100644 index 73ea506..0000000 --- a/Owin.Security.Providers/Yammer/Provider/YammerAuthenticationProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Owin.Security.Providers.Yammer.Provider -{ - /// - /// Default implementation. - /// - public class YammerAuthenticationProvider : IYammerAuthenticationProvider - { - /// - /// Initializes a - /// - public YammerAuthenticationProvider() - { - OnAuthenticated = context => Task.FromResult(null); - OnReturnEndpoint = context => Task.FromResult(null); - } - - /// - /// Gets or sets the function that is invoked when the Authenticated method is invoked. - /// - public Func OnAuthenticated { get; set; } - - /// - /// Gets or sets the function that is invoked when the ReturnEndpoint method is invoked. - /// - public Func OnReturnEndpoint { get; set; } - - /// - /// Invoked whenever Yammer succesfully authenticates a user - /// - /// Contains information about the login session as well as the user . - /// A representing the completed operation. - public virtual Task Authenticated(YammerAuthenticatedContext context) - { - return OnAuthenticated(context); - } - - /// - /// Invoked prior to the being saved in a local cookie and the browser being redirected to the originally requested URL. - /// - /// - /// A representing the completed operation. - public virtual Task ReturnEndpoint(YammerReturnEndpointContext context) - { - return OnReturnEndpoint(context); - } - } -} \ No newline at end of file diff --git a/Owin.Security.Providers/Yammer/Provider/YammerReturnEndpointContext.cs b/Owin.Security.Providers/Yammer/Provider/YammerReturnEndpointContext.cs deleted file mode 100644 index 1cd3dc1..0000000 --- a/Owin.Security.Providers/Yammer/Provider/YammerReturnEndpointContext.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Provider; - -namespace Owin.Security.Providers.Yammer.Provider -{ - /// - /// Provides context information to middleware providers. - /// - public class YammerReturnEndpointContext : ReturnEndpointContext - { - /// - /// - /// - /// OWIN environment - /// The authentication ticket - public YammerReturnEndpointContext( - IOwinContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/Owin.Security.Providers/Yammer/YammerAuthenticationExtensions.cs b/Owin.Security.Providers/Yammer/YammerAuthenticationExtensions.cs deleted file mode 100644 index aa31c9b..0000000 --- a/Owin.Security.Providers/Yammer/YammerAuthenticationExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace Owin.Security.Providers.Yammer -{ - public static class YammerAuthenticationExtensions - { - public static IAppBuilder UseYammerAuthentication(this IAppBuilder app, YammerAuthenticationOptions options) - { - if (app == null) - throw new ArgumentNullException("app"); - if (options == null) - throw new ArgumentNullException("options"); - - app.Use(typeof(YammerAuthenticationMiddleware), app, options); - - return app; - } - - public static IAppBuilder UseYammerAuthentication(this IAppBuilder app, string clientId, string clientSecret) - { - return app.UseYammerAuthentication(new YammerAuthenticationOptions - { - ClientId = clientId, - ClientSecret = clientSecret - }); - } - } -} diff --git a/Owin.Security.Providers/Yammer/YammerAuthenticationHandler.cs b/Owin.Security.Providers/Yammer/YammerAuthenticationHandler.cs deleted file mode 100644 index 84e23e4..0000000 --- a/Owin.Security.Providers/Yammer/YammerAuthenticationHandler.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Claims; -using System.Threading.Tasks; -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.Yammer.Provider; - -namespace Owin.Security.Providers.Yammer -{ - public class YammerAuthenticationHandler : AuthenticationHandler - { - private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; - private const string TokenEndpoint = "https://www.yammer.com/oauth2/access_token.json"; - private const string UserAuthenticationEndpoint = "https://www.yammer.com/dialog/oauth"; - - private readonly ILogger logger; - private readonly HttpClient httpClient; - - public YammerAuthenticationHandler(HttpClient httpClient, ILogger logger) - { - this.httpClient = httpClient; - this.logger = logger; - } - - protected override async Task AuthenticateCoreAsync() - { - AuthenticationProperties properties = null; - - 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]; - } - - properties = Options.StateDataFormat.Unprotect(state); - if (properties == null) - { - return null; - } - if (code == null) - { - throw new Exception(query["error"] + " - " + query["error_description"]); - } - - // 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; - - string endPoint = - TokenEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&client_secret=" + Uri.EscapeDataString(Options.ClientSecret) + - "&code=" + Uri.EscapeDataString(code); - - // Request the token - HttpResponseMessage tokenResponse = await httpClient.GetAsync(endPoint); - tokenResponse.EnsureSuccessStatusCode(); - string text = await tokenResponse.Content.ReadAsStringAsync(); - - // Deserializes the token response - dynamic response = JsonConvert.DeserializeObject(text); - string accessToken = (string)response.access_token.token; - - // Get the Yammer user - dynamic user = response.user; - var context = new YammerAuthenticatedContext(Context, user, accessToken); - context.Identity = new ClaimsIdentity( - Options.AuthenticationType, - ClaimsIdentity.DefaultNameClaimType, - ClaimsIdentity.DefaultRoleClaimType); - EnsureAcceptedNetwork(Options.AcceptedNetworks, context.Network); - - if (!string.IsNullOrEmpty(context.Id)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Name)) - { - context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.PrimaryEmail)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.PrimaryEmail, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.Url)) - { - context.Identity.AddClaim(new Claim(ClaimTypes.Uri, context.Url, XmlSchemaString, Options.AuthenticationType)); - } - if (!string.IsNullOrEmpty(context.AccessToken)) - { - context.Identity.AddClaim(new Claim("urn:Yammer:accesstoken", context.AccessToken, 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(null); - } - - AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); - - if (challenge != null) - { - string baseUri = - Request.Scheme + - Uri.SchemeDelimiter + - Request.Host + - Request.PathBase; - - string currentUri = - baseUri + - Request.Path + - Request.QueryString; - - string redirectUri = - baseUri + - Options.CallbackPath; - - AuthenticationProperties properties = challenge.Properties; - if (string.IsNullOrEmpty(properties.RedirectUri)) - { - properties.RedirectUri = currentUri; - } - - // OAuth2 10.12 CSRF - GenerateCorrelationId(properties); - - string state = Options.StateDataFormat.Protect(properties); - - string authorizationEndpoint = - UserAuthenticationEndpoint + - "?client_id=" + Uri.EscapeDataString(Options.ClientId) + - "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + - "&state=" + Uri.EscapeDataString(state); - - Response.Redirect(authorizationEndpoint); - } - - return Task.FromResult(null); - } - - public override async Task InvokeAsync() - { - return await InvokeReplyPathAsync(); - } - - private async Task InvokeReplyPathAsync() - { - if (Options.CallbackPath.HasValue && Options.CallbackPath == Request.Path) - { - // TODO: error responses - - AuthenticationTicket ticket = await AuthenticateAsync(); - if (ticket == null) - { - logger.WriteWarning("Invalid return state, unable to redirect."); - Response.StatusCode = 500; - return true; - } - - var context = new YammerReturnEndpointContext(Context, ticket); - context.SignInAsAuthenticationType = Options.SignInAsAuthenticationType; - context.RedirectUri = ticket.Properties.RedirectUri; - - await Options.Provider.ReturnEndpoint(context); - - if (context.SignInAsAuthenticationType != null && - context.Identity != null) - { - ClaimsIdentity grantIdentity = context.Identity; - if (!string.Equals(grantIdentity.AuthenticationType, context.SignInAsAuthenticationType, StringComparison.Ordinal)) - { - grantIdentity = new ClaimsIdentity(grantIdentity.Claims, context.SignInAsAuthenticationType, grantIdentity.NameClaimType, grantIdentity.RoleClaimType); - } - Context.Authentication.SignIn(context.Properties, grantIdentity); - } - - if (!context.IsRequestCompleted && context.RedirectUri != null) - { - string redirectUri = context.RedirectUri; - if (context.Identity == null) - { - // add a redirect hint that sign-in failed in some way - redirectUri = WebUtilities.AddQueryString(redirectUri, "error", "access_denied"); - } - Response.Redirect(redirectUri); - context.RequestCompleted(); - } - - return context.IsRequestCompleted; - } - return false; - } - - private void EnsureAcceptedNetwork(string[] validNetworks, string userNetwork) - { - if (validNetworks != null && validNetworks.Length > 0) - { - bool isValid = false; - foreach (string network in validNetworks) - { - if (userNetwork == network) - { - isValid = true; - break; - } - } - if (!isValid) throw new Exception("User is not in list of accepted networks"); - } - } - } -} \ No newline at end of file