diff --git a/Owin.Security.Providers/Owin.Security.Providers.csproj b/Owin.Security.Providers/Owin.Security.Providers.csproj
index 7808169..e952a9f 100644
--- a/Owin.Security.Providers/Owin.Security.Providers.csproj
+++ b/Owin.Security.Providers/Owin.Security.Providers.csproj
@@ -273,6 +273,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/Owin.Security.Providers/VisualStudio/Constants.cs b/Owin.Security.Providers/VisualStudio/Constants.cs
new file mode 100644
index 0000000..9d32b17
--- /dev/null
+++ b/Owin.Security.Providers/VisualStudio/Constants.cs
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 0000000..2ea50b3
--- /dev/null
+++ b/Owin.Security.Providers/VisualStudio/Provider/IVisualStudioAuthenticationProvider.cs
@@ -0,0 +1,23 @@
+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
new file mode 100644
index 0000000..41ba043
--- /dev/null
+++ b/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticatedContext.cs
@@ -0,0 +1,94 @@
+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
new file mode 100644
index 0000000..43af752
--- /dev/null
+++ b/Owin.Security.Providers/VisualStudio/Provider/VisualStudioAuthenticationProvider.cs
@@ -0,0 +1,47 @@
+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