diff --git a/Owin.Security.Providers/Owin.Security.Providers.csproj b/Owin.Security.Providers/Owin.Security.Providers.csproj
index 39672a5..81130ee 100644
--- a/Owin.Security.Providers/Owin.Security.Providers.csproj
+++ b/Owin.Security.Providers/Owin.Security.Providers.csproj
@@ -382,6 +382,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Owin.Security.Providers/VKontakte/Constants.cs b/Owin.Security.Providers/VKontakte/Constants.cs
new file mode 100644
index 0000000..309dc48
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/Constants.cs
@@ -0,0 +1,7 @@
+namespace Owin.Security.Providers.VKontakte
+{
+ internal static class Constants
+ {
+ public const string DefaultAuthenticationType = "VK";
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/Provider/IVKontakteAuthenticationProvider.cs b/Owin.Security.Providers/VKontakte/Provider/IVKontakteAuthenticationProvider.cs
new file mode 100644
index 0000000..300110b
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/Provider/IVKontakteAuthenticationProvider.cs
@@ -0,0 +1,24 @@
+using System.Threading.Tasks;
+
+namespace Owin.Security.Providers.VKontakte.Provider
+{
+ ///
+ /// Specifies callback methods which the invokes to enable developer control over the authentication process. />
+ ///
+ public interface IVKontakteAuthenticationProvider
+ {
+ ///
+ /// Invoked whenever GitHub succesfully authenticates a user
+ ///
+ /// Contains information about the login session as well as the user .
+ /// A representing the completed operation.
+ Task Authenticated(VKontakteAuthenticatedContext 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(VKontakteReturnEndpointContext context);
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticatedContext.cs b/Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticatedContext.cs
new file mode 100644
index 0000000..eba6d76
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticatedContext.cs
@@ -0,0 +1,74 @@
+// 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.VKontakte.Provider
+{
+ ///
+ /// Contains information about the login session as well as the user .
+ ///
+ public class VKontakteAuthenticatedContext : BaseContext
+ {
+ ///
+ /// Initializes a
+ ///
+ /// The OWIN environment
+ /// The JSON-serialized user
+ /// VK Access token
+ public VKontakteAuthenticatedContext(IOwinContext context, JObject user, string accessToken)
+ : base(context)
+ {
+ User = user;
+ AccessToken = accessToken;
+
+ Id = TryGetValue(user, "uid");
+ string firstName = TryGetValue(user, "first_name");
+ string lastName = TryGetValue(user, "last_name");
+ UserName = $"{firstName} {lastName}";
+ }
+
+ ///
+ /// Gets the JSON-serialized user
+ ///
+ ///
+ /// Contains the VK user obtained from the User Info endpoint. By default this is https://api.vk.com/method/users.get but it can be
+ /// overridden in the options
+ ///
+ public JObject User { get; private set; }
+
+ ///
+ /// Gets the VK access token
+ ///
+ public string AccessToken { get; private set; }
+
+ ///
+ /// Gets the VK user ID
+ ///
+ public string Id { get; private set; }
+
+ ///
+ /// Gets the user's name
+ ///
+ 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/VKontakte/Provider/VKontakteAuthenticationProvider.cs b/Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticationProvider.cs
new file mode 100644
index 0000000..30e7827
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticationProvider.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Owin.Security.Providers.VKontakte.Provider
+{
+ ///
+ /// Default implementation.
+ ///
+ public class VKontakteAuthenticationProvider : IVKontakteAuthenticationProvider
+ {
+ ///
+ /// Initializes a
+ ///
+ public VKontakteAuthenticationProvider()
+ {
+ 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 VK succesfully authenticates a user
+ ///
+ /// Contains information about the login session as well as the user .
+ /// A representing the completed operation.
+ public virtual Task Authenticated(VKontakteAuthenticatedContext 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(VKontakteReturnEndpointContext context)
+ {
+ return OnReturnEndpoint(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/Provider/VKontakteReturnEndpointContext.cs b/Owin.Security.Providers/VKontakte/Provider/VKontakteReturnEndpointContext.cs
new file mode 100644
index 0000000..4dde698
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/Provider/VKontakteReturnEndpointContext.cs
@@ -0,0 +1,26 @@
+// 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.VKontakte.Provider
+{
+ ///
+ /// Provides context information to middleware providers.
+ ///
+ public class VKontakteReturnEndpointContext : ReturnEndpointContext
+ {
+ ///
+ ///
+ ///
+ /// OWIN environment
+ /// The authentication ticket
+ public VKontakteReturnEndpointContext(
+ IOwinContext context,
+ AuthenticationTicket ticket)
+ : base(context, ticket)
+ {
+ }
+ }
+}
diff --git a/Owin.Security.Providers/VKontakte/VKontakteAuthenticationEndpoints.cs b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationEndpoints.cs
new file mode 100644
index 0000000..83089e5
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationEndpoints.cs
@@ -0,0 +1,29 @@
+namespace Owin.Security.Providers.VKontakte
+{
+ public class VKontakteAuthenticationEndpoints
+ {
+ ///
+ /// Endpoint which is used to redirect users to request VK access
+ ///
+ ///
+ /// Defaults to https://oauth.vk.com/authorize
+ ///
+ public string AuthorizationEndpoint { get; set; }
+
+ ///
+ /// Endpoint which is used to exchange code for access token
+ ///
+ ///
+ /// Defaults to https://oauth.vk.com/access_token
+ ///
+ public string TokenEndpoint { get; set; }
+
+ ///
+ /// Endpoint which is used to obtain user information after authentication
+ ///
+ ///
+ /// Defaults to https://api.vk.com/method/users.get
+ ///
+ public string UserInfoEndpoint { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/VKontakteAuthenticationExtensions.cs b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationExtensions.cs
new file mode 100644
index 0000000..bb7f666
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Owin.Security.Providers.VKontakte
+{
+ public static class VKontakteAuthenticationExtensions
+ {
+ public static IAppBuilder UseVKontakteAuthentication(this IAppBuilder app,
+ VKontakteAuthenticationOptions options)
+ {
+ if (app == null)
+ throw new ArgumentNullException(nameof(app));
+ if (options == null)
+ throw new ArgumentNullException(nameof(options));
+
+ app.Use(typeof(VKontakteAuthenticationMiddleware), app, options);
+
+ return app;
+ }
+
+ public static IAppBuilder UseVKontakteAuthentication(this IAppBuilder app, string clientId, string clientSecret)
+ {
+ return app.UseVKontakteAuthentication(new VKontakteAuthenticationOptions
+ {
+ ClientId = clientId,
+ ClientSecret = clientSecret
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/VKontakteAuthenticationHandler.cs b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationHandler.cs
new file mode 100644
index 0000000..5d024cf
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationHandler.cs
@@ -0,0 +1,239 @@
+using System;
+using System.Collections.Generic;
+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.Infrastructure;
+using Newtonsoft.Json.Linq;
+using Owin.Security.Providers.VKontakte.Provider;
+
+namespace Owin.Security.Providers.VKontakte
+{
+ public class VKontakteAuthenticationHandler : AuthenticationHandler
+ {
+ private const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
+
+ private readonly ILogger logger;
+ private readonly HttpClient httpClient;
+
+ public VKontakteAuthenticationHandler(HttpClient httpClient, ILogger logger)
+ {
+ this.httpClient = httpClient;
+ this.logger = logger;
+ }
+
+ public override async Task InvokeAsync()
+ {
+ return await InvokeReplyPathAsync();
+ }
+
+ 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)}
+ &state={Uri.EscapeDataString(state)}&display={Uri.EscapeDataString(Options.Display)}";
+
+ Response.Redirect(authorizationEndpoint);
+ }
+
+ return Task.FromResult(null);
+ }
+
+ protected override async Task AuthenticateCoreAsync()
+ {
+ AuthenticationProperties properties = null;
+
+ try
+ {
+ string authorizationCode = GetParameterValueFromRequest("code");
+ string state = GetParameterValueFromRequest("state");
+
+ properties = Options.StateDataFormat.Unprotect(state);
+ if (properties == null)
+ {
+ return null;
+ }
+
+ // OAuth2 10.12 CSRF
+ if (!ValidateCorrelationId(properties, logger))
+ {
+ return new AuthenticationTicket(null, properties);
+ }
+
+ JObject response = await GetAuthorizationToken(authorizationCode);
+ string accessToken = (string)response["access_token"];
+
+ JObject user = await GetUser(response, accessToken);
+
+ VKontakteAuthenticatedContext context = CreateAuthenticatedContext(user, accessToken, 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);
+ }
+
+ private string GetParameterValueFromRequest(string parameterName)
+ {
+ string value = null;
+ IReadableStringCollection query = Request.Query;
+ IList values = query.GetValues(parameterName);
+ if (values != null && values.Count == 1)
+ {
+ value = values[0];
+ }
+ return value;
+ }
+
+ private VKontakteAuthenticatedContext CreateAuthenticatedContext(JObject user, string accessToken,
+ AuthenticationProperties properties)
+ {
+ var context = new VKontakteAuthenticatedContext(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;
+ return context;
+ }
+
+ private async Task GetUser(JObject response, string accessToken)
+ {
+ int userId = (int) response["user_id"];
+
+ // Get the VK user
+ var userRequestUri =
+ new Uri(
+ $@"{Options.Endpoints.UserInfoEndpoint}?access_token={Uri.EscapeDataString(accessToken)}&user_id{userId}");
+ HttpResponseMessage userResponse = await httpClient.GetAsync(userRequestUri, Request.CallCancelled);
+ userResponse.EnsureSuccessStatusCode();
+
+ var userReposnseAsString = await userResponse.Content.ReadAsStringAsync();
+ var user = JObject.Parse(userReposnseAsString)["response"];
+ return (JObject)user[0];
+ }
+
+ private async Task GetAuthorizationToken(string authorizationCode)
+ {
+ string redirectUri = $"{Request.Scheme}://{Request.Host}{Request.PathBase}{Options.CallbackPath}";
+
+ // Build up the body for the token request
+ var body = new Dictionary
+ {
+ {"code", authorizationCode},
+ {"redirect_uri", redirectUri},
+ {"client_id", Options.ClientId},
+ {"client_secret", Options.ClientSecret}
+ };
+
+ // Request the token
+ HttpResponseMessage tokenResponse =
+ await httpClient.PostAsync(Options.Endpoints.TokenEndpoint, new FormUrlEncodedContent(body));
+ tokenResponse.EnsureSuccessStatusCode();
+ string tokenResponseAsString = await tokenResponse.Content.ReadAsStringAsync();
+
+ // Deserializes the token response
+ JObject response = JObject.Parse(tokenResponseAsString);
+ return response;
+ }
+
+ 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 VKontakteReturnEndpointContext(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/VKontakte/VKontakteAuthenticationMiddleware.cs b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationMiddleware.cs
new file mode 100644
index 0000000..2ae5ee3
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationMiddleware.cs
@@ -0,0 +1,91 @@
+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.VKontakte.Provider;
+
+namespace Owin.Security.Providers.VKontakte
+{
+ public class VKontakteAuthenticationMiddleware : AuthenticationMiddleware
+ {
+ private readonly HttpClient httpClient;
+ private readonly ILogger logger;
+
+ public VKontakteAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app,
+ VKontakteAuthenticationOptions 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"));
+
+ SetDefaults(app);
+
+ logger = app.CreateLogger();
+
+ httpClient = new HttpClient(ResolveHttpMessageHandler(Options))
+ {
+ Timeout = Options.BackchannelTimeout,
+ MaxResponseContentBufferSize = 1024 * 1024 * 10,
+ };
+ httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft Owin VKontakte 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 VKontakteAuthenticationHandler(httpClient, logger);
+ }
+
+ private HttpMessageHandler ResolveHttpMessageHandler(VKontakteAuthenticationOptions 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;
+ }
+ private void SetDefaults(IAppBuilder app)
+ {
+ if (Options.Provider == null)
+ Options.Provider = new VKontakteAuthenticationProvider();
+
+ if (Options.StateDataFormat == null)
+ {
+ IDataProtector dataProtector = app.CreateDataProtector(
+ typeof(VKontakteAuthenticationMiddleware).FullName,
+ Options.AuthenticationType, "v1");
+ Options.StateDataFormat = new PropertiesDataFormat(dataProtector);
+ }
+
+ if (String.IsNullOrEmpty(Options.SignInAsAuthenticationType))
+ Options.SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Owin.Security.Providers/VKontakte/VKontakteAuthenticationOptions.cs b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationOptions.cs
new file mode 100644
index 0000000..2659ccc
--- /dev/null
+++ b/Owin.Security.Providers/VKontakte/VKontakteAuthenticationOptions.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using Microsoft.Owin;
+using Microsoft.Owin.Security;
+using Owin.Security.Providers.VKontakte.Provider;
+
+namespace Owin.Security.Providers.VKontakte
+{
+ public class VKontakteAuthenticationOptions : AuthenticationOptions
+ {
+ private const string AuthorizationEndPoint = "https://oauth.vk.com/authorize";
+ private const string TokenEndpoint = "https://oauth.vk.com/access_token";
+ private const string UserInfoEndpoint = "https://api.vk.com/method/users.get";
+ private const string DefaultCallbackPath = "/signin-vk";
+ private const string DefaultDisplayMode = "page";
+
+ ///
+ /// Gets or sets the a pinned certificate validator to use to validate the endpoints used
+ /// in back channel communications belong to VK.
+ ///
+ ///
+ /// 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 VK.
+ /// 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 VK.
+ ///
+ ///
+ /// 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-vk".
+ ///
+ 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 VK supplied Client ID
+ ///
+ public string ClientId { get; set; }
+
+ ///
+ /// Gets or sets the VK supplied Client Secret
+ ///
+ public string ClientSecret { get; set; }
+
+ ///
+ /// Gets the sets of OAuth endpoints used to authenticate against VK.
+ ///
+ public VKontakteAuthenticationEndpoints Endpoints { get; set; }
+
+ ///
+ /// Gets or sets the used in the authentication events
+ ///
+ public IVKontakteAuthenticationProvider Provider { get; set; }
+
+ ///
+ /// A list of permissions to request.
+ ///
+ public IList Scope { get; set; }
+
+ ///
+ /// Type of displayed page. Possible values: page, popup and mobile. Default: page.
+ ///
+ public string Display { 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 VKontakteAuthenticationOptions()
+ : base(Constants.DefaultAuthenticationType)
+ {
+ Caption = Constants.DefaultAuthenticationType;
+ CallbackPath = new PathString(DefaultCallbackPath);
+ AuthenticationMode = AuthenticationMode.Passive;
+ Display = DefaultDisplayMode;
+ Scope = new List();
+ BackchannelTimeout = TimeSpan.FromSeconds(60);
+ Endpoints = new VKontakteAuthenticationEndpoints
+ {
+ AuthorizationEndpoint = AuthorizationEndPoint,
+ TokenEndpoint = TokenEndpoint,
+ UserInfoEndpoint = UserInfoEndpoint
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
index 4be53f6..7313a78 100755
--- a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
+++ b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs
@@ -41,6 +41,7 @@ using Owin.Security.Providers.Backlog;
using Owin.Security.Providers.Vimeo;
using Owin.Security.Providers.Fitbit;
using Owin.Security.Providers.Onshape;
+using Owin.Security.Providers.VKontakte;
namespace OwinOAuthProvidersDemo
{
@@ -308,6 +309,8 @@ namespace OwinOAuthProvidersDemo
// CallbackPath = new PathString("/oauthRedirect"),
// Hostname = "partner.dev.onshape.com"
//});
+
+ //app.UseVKontakteAuthentication("", "");
}
}
}
diff --git a/README.md b/README.md
index c3a8d90..6082544 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ Provides a set of extra authentication providers for OWIN ([Project Katana](http
- Untappd
- Vimeo
- Visual Studio Online
+ - VKontakte
- Wordpress
- Yahoo
- Yammer