From 5167e83e94dd148a0d86787cb1ea6c2123d3d6b2 Mon Sep 17 00:00:00 2001 From: Nikita Gusev Date: Wed, 30 Dec 2015 17:51:37 +0100 Subject: [PATCH 1/2] Added VKontakte support --- .../Owin.Security.Providers.csproj | 10 + .../VKontakte/Constants.cs | 7 + .../IVKontakteAuthenticationProvider.cs | 24 ++ .../Provider/VKontakteAuthenticatedContext.cs | 74 ++++++ .../VKontakteAuthenticationProvider.cs | 50 ++++ .../VKontakteReturnEndpointContext.cs | 26 ++ .../VKontakteAuthenticationEndpoints.cs | 29 +++ .../VKontakteAuthenticationExtensions.cs | 29 +++ .../VKontakteAuthenticationHandler.cs | 239 ++++++++++++++++++ .../VKontakteAuthenticationMiddleware.cs | 91 +++++++ .../VKontakteAuthenticationOptions.cs | 123 +++++++++ .../App_Start/Startup.Auth.cs | 5 +- README.md | 1 + 13 files changed, 707 insertions(+), 1 deletion(-) create mode 100644 Owin.Security.Providers/VKontakte/Constants.cs create mode 100644 Owin.Security.Providers/VKontakte/Provider/IVKontakteAuthenticationProvider.cs create mode 100644 Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticatedContext.cs create mode 100644 Owin.Security.Providers/VKontakte/Provider/VKontakteAuthenticationProvider.cs create mode 100644 Owin.Security.Providers/VKontakte/Provider/VKontakteReturnEndpointContext.cs create mode 100644 Owin.Security.Providers/VKontakte/VKontakteAuthenticationEndpoints.cs create mode 100644 Owin.Security.Providers/VKontakte/VKontakteAuthenticationExtensions.cs create mode 100644 Owin.Security.Providers/VKontakte/VKontakteAuthenticationHandler.cs create mode 100644 Owin.Security.Providers/VKontakte/VKontakteAuthenticationMiddleware.cs create mode 100644 Owin.Security.Providers/VKontakte/VKontakteAuthenticationOptions.cs diff --git a/Owin.Security.Providers/Owin.Security.Providers.csproj b/Owin.Security.Providers/Owin.Security.Providers.csproj index 429a239..5509473 100644 --- a/Owin.Security.Providers/Owin.Security.Providers.csproj +++ b/Owin.Security.Providers/Owin.Security.Providers.csproj @@ -373,6 +373,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..05deff5 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 { @@ -80,7 +81,7 @@ namespace OwinOAuthProvidersDemo //app.UseTripItAuthentication("", ""); - //app.UseGitHubAuthentication("", ""); + //app.UseGitHubAuthentication("c842f3dfb895808f6585", "5354f5cd141169d57ecb5e058bb8a4529685947f"); //app.UseBufferAuthentication("", ""); @@ -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 From d0cf3a0543b4e2db69f129f2c88b3a19db93ca99 Mon Sep 17 00:00:00 2001 From: Nikita Gusev Date: Wed, 30 Dec 2015 17:55:58 +0100 Subject: [PATCH 2/2] Deleted unneded settings --- OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs index 05deff5..7313a78 100755 --- a/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs +++ b/OwinOAuthProvidersDemo/App_Start/Startup.Auth.cs @@ -81,7 +81,7 @@ namespace OwinOAuthProvidersDemo //app.UseTripItAuthentication("", ""); - //app.UseGitHubAuthentication("c842f3dfb895808f6585", "5354f5cd141169d57ecb5e058bb8a4529685947f"); + //app.UseGitHubAuthentication("", ""); //app.UseBufferAuthentication("", "");