FIXME SR is private
parent
dac93a6206
commit
8b607e2606
@ -1,35 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Yavsc.Models.Blog;
|
|
||||||
using Yavsc.ViewModels.Auth;
|
|
||||||
|
|
||||||
namespace Yavsc.AuthorizationHandlers
|
|
||||||
{
|
|
||||||
public class BlogViewHandler : AuthorizationHandler<ViewRequirement, BlogPost>
|
|
||||||
{
|
|
||||||
protected override void Handle(AuthorizationContext context, ViewRequirement requirement, BlogPost resource)
|
|
||||||
{
|
|
||||||
bool ok=false;
|
|
||||||
if (resource.Visible) {
|
|
||||||
if (resource.ACL==null)
|
|
||||||
ok=true;
|
|
||||||
else if (resource.ACL.Count==0) ok=true;
|
|
||||||
else {
|
|
||||||
if (context.User.IsSignedIn()) {
|
|
||||||
var uid = context.User.GetUserId();
|
|
||||||
if (resource.ACL.Any(a=>a.Allowed!=null && a.Allowed.Members.Any(m=>m.MemberId == uid )))
|
|
||||||
ok=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ok) context.Succeed(requirement);
|
|
||||||
else {
|
|
||||||
if (context.User.IsInRole(Constants.AdminGroupName) ||
|
|
||||||
context.User.IsInRole(Constants.BlogModeratorGroupName))
|
|
||||||
context.Succeed(requirement);
|
|
||||||
else context.Fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Yavsc.ViewModels.Auth;
|
|
||||||
|
|
||||||
namespace Yavsc.AuthorizationHandlers
|
|
||||||
{
|
|
||||||
public class HasBadgeHandler : AuthorizationHandler<PrivateChatEntryRequirement>
|
|
||||||
{
|
|
||||||
protected override void Handle(AuthorizationContext context, PrivateChatEntryRequirement requirement)
|
|
||||||
{
|
|
||||||
if (!context.User.HasClaim(c => c.Type == "BadgeNumber" &&
|
|
||||||
c.Issuer == Startup.Authority))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
context.Succeed(requirement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Yavsc.ViewModels.Auth;
|
|
||||||
|
|
||||||
namespace Yavsc.AuthorizationHandlers
|
|
||||||
{
|
|
||||||
public class HasTemporaryPassHandler : AuthorizationHandler<PrivateChatEntryRequirement>
|
|
||||||
{
|
|
||||||
protected override void Handle(AuthorizationContext context, PrivateChatEntryRequirement requirement)
|
|
||||||
{
|
|
||||||
if (!context.User.HasClaim(c => c.Type == "TemporaryBadgeExpiry" &&
|
|
||||||
c.Issuer == Startup.Authority))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var temporaryBadgeExpiry =
|
|
||||||
Convert.ToDateTime(context.User.FindFirst(
|
|
||||||
c => c.Type == "TemporaryBadgeExpiry" &&
|
|
||||||
c.Issuer == Startup.Authority).Value);
|
|
||||||
|
|
||||||
if (temporaryBadgeExpiry > DateTime.Now)
|
|
||||||
{
|
|
||||||
context.Succeed(requirement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Yavsc.Server.Models.IT.SourceCode;
|
|
||||||
using Yavsc.ViewModels.Auth;
|
|
||||||
|
|
||||||
namespace Yavsc.AuthorizationHandlers
|
|
||||||
{
|
|
||||||
public class ManageGitHookHandler: AuthorizationHandler<EditRequirement, GitRepositoryReference>
|
|
||||||
{
|
|
||||||
protected override void Handle(AuthorizationContext context, EditRequirement requirement, GitRepositoryReference resource)
|
|
||||||
{
|
|
||||||
if (context.User.IsInRole("FrontOffice"))
|
|
||||||
context.Succeed(requirement);
|
|
||||||
else if (context.User.Identity.IsAuthenticated)
|
|
||||||
context.Succeed(requirement);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Yavsc.Services;
|
|
||||||
using Yavsc.ViewModels.Auth;
|
|
||||||
|
|
||||||
namespace Yavsc.AuthorizationHandlers
|
|
||||||
{
|
|
||||||
|
|
||||||
public class ViewFileHandler : AuthorizationHandler<ViewRequirement, ViewFileContext>
|
|
||||||
{
|
|
||||||
readonly IFileSystemAuthManager _authManager;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
|
|
||||||
public ViewFileHandler(IFileSystemAuthManager authManager, ILoggerFactory logFactory)
|
|
||||||
{
|
|
||||||
_authManager = authManager;
|
|
||||||
_logger = logFactory.CreateLogger<ViewFileHandler>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Handle(AuthorizationContext context, ViewRequirement requirement, ViewFileContext fileContext)
|
|
||||||
{
|
|
||||||
|
|
||||||
var rights = _authManager.GetFilePathAccess(context.User, fileContext.File);
|
|
||||||
_logger.LogInformation("Got access value : " + rights);
|
|
||||||
if ((rights & FileAccessRight.Read) > 0)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Allowing access");
|
|
||||||
context.Succeed(requirement);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Denying access");
|
|
||||||
context.Fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Builder;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Extension methods to add Google authentication capabilities to an HTTP application pipeline.
|
|
||||||
/// </summary>
|
|
||||||
public static class GoogleAppBuilderExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Google authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
|
||||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
|
||||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
if (app == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(app));
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.UseMiddleware<GoogleMiddleware>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Google authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
|
||||||
/// <param name="options">A <see cref="YavscGoogleOptions"/> that specifies options for the middleware.</param>
|
|
||||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
|
||||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app, YavscGoogleOptions options)
|
|
||||||
{
|
|
||||||
if (app == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(app));
|
|
||||||
}
|
|
||||||
if (options == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.UseMiddleware<GoogleMiddleware>(options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,141 +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.AspNet.Authentication;
|
|
||||||
using Microsoft.AspNet.Authentication.OAuth;
|
|
||||||
using Microsoft.AspNet.Http.Authentication;
|
|
||||||
using Microsoft.AspNet.WebUtilities;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth
|
|
||||||
{
|
|
||||||
internal class GoogleHandler : OAuthHandler<YavscGoogleOptions>
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
public GoogleHandler(HttpClient httpClient,ILogger logger)
|
|
||||||
: base(httpClient)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity,
|
|
||||||
AuthenticationProperties properties, OAuthTokenResponse tokens
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Getting user info from Google ...");
|
|
||||||
// Get the Google user
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
|
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
|
|
||||||
|
|
||||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
|
||||||
|
|
||||||
var identifier = GoogleHelper.GetId(payload);
|
|
||||||
|
|
||||||
|
|
||||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme);
|
|
||||||
var context = new GoogleOAuthCreatingTicketContext(Context, Options, Backchannel, tokens, ticket, identifier);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(identifier))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var givenName = GoogleHelper.GetGivenName(payload);
|
|
||||||
if (!string.IsNullOrEmpty(givenName))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.GivenName, givenName, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var familyName = GoogleHelper.GetFamilyName(payload);
|
|
||||||
if (!string.IsNullOrEmpty(familyName))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.Surname, familyName, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = GoogleHelper.GetName(payload);
|
|
||||||
if (!string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var email = GoogleHelper.GetEmail(payload);
|
|
||||||
if (!string.IsNullOrEmpty(email))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var profile = GoogleHelper.GetProfile(payload);
|
|
||||||
if (!string.IsNullOrEmpty(profile))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim("urn:google:profile", profile, ClaimValueTypes.String, Options.ClaimsIssuer));
|
|
||||||
}
|
|
||||||
|
|
||||||
await Options.Events.CreatingTicket(context);
|
|
||||||
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
protected override Task<OAuthTokenResponse> ExchangeCodeAsync(string code, string ruri)
|
|
||||||
{
|
|
||||||
var redirectUri = $"https://{Startup.Authority}{Options.CallbackPath}";
|
|
||||||
return base.ExchangeCodeAsync(code,redirectUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Abstract this properties override pattern into the base class?
|
|
||||||
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
|
|
||||||
{
|
|
||||||
|
|
||||||
var scope = FormatScope();
|
|
||||||
var queryStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
{ "response_type", "code" },
|
|
||||||
{ "client_id", Options.ClientId }
|
|
||||||
};
|
|
||||||
// this runtime may not known this value,
|
|
||||||
// it should be get from config,
|
|
||||||
// And always be using a secure sheme ... since Google won't support anymore insecure ones.
|
|
||||||
_logger.LogInformation ($"Redirect uri was : {redirectUri}");
|
|
||||||
|
|
||||||
redirectUri = $"https://{Startup.Authority}{Options.CallbackPath}";
|
|
||||||
queryStrings.Add("redirect_uri", redirectUri);
|
|
||||||
|
|
||||||
_logger.LogInformation ($"Using redirect uri {redirectUri}");
|
|
||||||
|
|
||||||
AddQueryString(queryStrings, properties, "scope", scope);
|
|
||||||
|
|
||||||
AddQueryString(queryStrings, properties, "access_type", Options.AccessType);
|
|
||||||
AddQueryString(queryStrings, properties, "approval_prompt");
|
|
||||||
AddQueryString(queryStrings, properties, "login_hint");
|
|
||||||
|
|
||||||
var state = Options.StateDataFormat.Protect(properties);
|
|
||||||
queryStrings.Add("state", state);
|
|
||||||
|
|
||||||
var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);
|
|
||||||
return authorizationEndpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void AddQueryString(IDictionary<string, string> queryStrings, AuthenticationProperties properties,
|
|
||||||
string name, string defaultValue = null)
|
|
||||||
{
|
|
||||||
string value;
|
|
||||||
if (!properties.Items.TryGetValue(name, out value))
|
|
||||||
{
|
|
||||||
value = defaultValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove the parameter from AuthenticationProperties so it won't be serialized to state parameter
|
|
||||||
properties.Items.Remove(name);
|
|
||||||
}
|
|
||||||
queryStrings[name] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
/// <summary>
|
|
||||||
/// Contains static methods that allow to extract user's information from a <see cref="JObject"/>
|
|
||||||
/// instance retrieved from Google after a successful authentication process.
|
|
||||||
/// </summary>
|
|
||||||
public static class GoogleHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Google user ID.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetId(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.Value<string>("id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the user's name.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetName(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.Value<string>("displayName");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the user's given name.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetGivenName(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TryGetValue(user, "name", "givenName");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the user's family name.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetFamilyName(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TryGetValue(user, "name", "familyName");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the user's profile link.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetProfile(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.Value<string>("url");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the user's email.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetEmail(JObject user)
|
|
||||||
{
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TryGetFirstValue(user, "emails", "value");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the given subProperty from a property.
|
|
||||||
private static string TryGetValue(JObject user, string propertyName, string subProperty)
|
|
||||||
{
|
|
||||||
JToken value;
|
|
||||||
if (user.TryGetValue(propertyName, out value))
|
|
||||||
{
|
|
||||||
var subObject = JObject.Parse(value.ToString());
|
|
||||||
if (subObject != null && subObject.TryGetValue(subProperty, out value))
|
|
||||||
{
|
|
||||||
return value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GoogleApisAuthOAuth2
|
|
||||||
public static ServiceAccountCredential GetGoogleApiCredentials (string[] scopes)
|
|
||||||
{
|
|
||||||
String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE";
|
|
||||||
|
|
||||||
string private_key = Startup.GoogleSettings.Account.private_key;
|
|
||||||
|
|
||||||
string secret = Startup.GoogleSettings.ClientSecret;
|
|
||||||
|
|
||||||
|
|
||||||
var certificate = new X509Certificate2(@"key.p12", secret, X509KeyStorageFlags.Exportable);
|
|
||||||
|
|
||||||
return new ServiceAccountCredential(
|
|
||||||
new ServiceAccountCredential.Initializer(serviceAccountEmail)
|
|
||||||
{
|
|
||||||
Scopes = scopes
|
|
||||||
}.FromCertificate(certificate));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Get the given subProperty from a list property.
|
|
||||||
private static string TryGetFirstValue(JObject user, string propertyName, string subProperty)
|
|
||||||
{
|
|
||||||
JToken value;
|
|
||||||
if (user.TryGetValue(propertyName, out value))
|
|
||||||
{
|
|
||||||
var array = JArray.Parse(value.ToString());
|
|
||||||
if (array != null && array.Count > 0)
|
|
||||||
{
|
|
||||||
var subObject = JObject.Parse(array.First.ToString());
|
|
||||||
if (subObject != null)
|
|
||||||
{
|
|
||||||
if (subObject.TryGetValue(subProperty, out value))
|
|
||||||
{
|
|
||||||
return value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Authentication;
|
|
||||||
using Microsoft.AspNet.Authentication.OAuth;
|
|
||||||
using Microsoft.AspNet.Builder;
|
|
||||||
using Microsoft.AspNet.DataProtection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.OptionsModel;
|
|
||||||
using Microsoft.Extensions.WebEncoders;
|
|
||||||
namespace Yavsc.Auth
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An ASP.NET Core middleware for authenticating users using Google OAuth 2.0.
|
|
||||||
/// </summary>
|
|
||||||
public class GoogleMiddleware : OAuthMiddleware<YavscGoogleOptions>
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new <see cref="GoogleMiddleware"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
|
||||||
/// <param name="dataProtectionProvider"></param>
|
|
||||||
/// <param name="loggerFactory"></param>
|
|
||||||
/// <param name="encoder"></param>
|
|
||||||
/// <param name="sharedOptions"></param>
|
|
||||||
/// <param name="options">Configuration options for the middleware.</param>
|
|
||||||
public GoogleMiddleware(
|
|
||||||
RequestDelegate next,
|
|
||||||
IDataProtectionProvider dataProtectionProvider,
|
|
||||||
ILoggerFactory loggerFactory,
|
|
||||||
UrlEncoder encoder,
|
|
||||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
|
||||||
YavscGoogleOptions options)
|
|
||||||
: base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (dataProtectionProvider == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(dataProtectionProvider));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loggerFactory == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(loggerFactory));
|
|
||||||
}
|
|
||||||
_logger = loggerFactory.CreateLogger<GoogleMiddleware>();
|
|
||||||
|
|
||||||
if (encoder == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(encoder));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sharedOptions == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(sharedOptions));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override AuthenticationHandler<YavscGoogleOptions> CreateHandler()
|
|
||||||
{
|
|
||||||
return new GoogleHandler(Backchannel,_logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System.Net.Http;
|
|
||||||
using Microsoft.AspNet.Authentication;
|
|
||||||
using Microsoft.AspNet.Authentication.OAuth;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth {
|
|
||||||
|
|
||||||
|
|
||||||
public class GoogleOAuthCreatingTicketContext : OAuthCreatingTicketContext {
|
|
||||||
public GoogleOAuthCreatingTicketContext(HttpContext context, OAuthOptions options,
|
|
||||||
HttpClient backchannel, OAuthTokenResponse tokens, AuthenticationTicket ticket, string googleUserId )
|
|
||||||
: base( context, options, backchannel, tokens )
|
|
||||||
{
|
|
||||||
_ticket = ticket;
|
|
||||||
_googleUserId = googleUserId;
|
|
||||||
Principal = ticket.Principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly AuthenticationTicket _ticket;
|
|
||||||
readonly string _googleUserId;
|
|
||||||
|
|
||||||
public AuthenticationTicket Ticket { get { return _ticket; } }
|
|
||||||
|
|
||||||
public string GoogleUserId { get { return _googleUserId; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
using Microsoft.AspNet.Authentication.OAuth;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth
|
|
||||||
{
|
|
||||||
public static class YavscGoogleDefaults
|
|
||||||
{
|
|
||||||
public const string AuthenticationScheme = "Google";
|
|
||||||
|
|
||||||
public static readonly string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth";
|
|
||||||
|
|
||||||
public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v3/token";
|
|
||||||
|
|
||||||
public static readonly string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configuration options for <see cref="GoogleMiddleware"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class YavscGoogleOptions : OAuthOptions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new <see cref="YavscGoogleOptions"/>.
|
|
||||||
/// </summary>
|
|
||||||
public YavscGoogleOptions()
|
|
||||||
{
|
|
||||||
AuthenticationScheme = YavscGoogleDefaults.AuthenticationScheme;
|
|
||||||
DisplayName = AuthenticationScheme;
|
|
||||||
CallbackPath = new PathString("/signin-google");
|
|
||||||
AuthorizationEndpoint = YavscGoogleDefaults.AuthorizationEndpoint;
|
|
||||||
TokenEndpoint = YavscGoogleDefaults.TokenEndpoint;
|
|
||||||
UserInformationEndpoint = YavscGoogleDefaults.UserInformationEndpoint;
|
|
||||||
Scope.Add("openid");
|
|
||||||
Scope.Add("profile");
|
|
||||||
Scope.Add("email");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// access_type. Set to 'offline' to request a refresh token.
|
|
||||||
/// </summary>
|
|
||||||
public string AccessType { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IdentityModel.Tokens;
|
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using System.Security.Claims;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth
|
|
||||||
{
|
|
||||||
|
|
||||||
public class MonoJwtSecurityTokenHandler : JwtSecurityTokenHandler
|
|
||||||
{
|
|
||||||
|
|
||||||
public MonoJwtSecurityTokenHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override JwtSecurityToken CreateToken(
|
|
||||||
string issuer,
|
|
||||||
string audience, ClaimsIdentity subject,
|
|
||||||
DateTime? notBefore, DateTime? expires, DateTime? issuedAt,
|
|
||||||
SigningCredentials signingCredentials
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
|
|
||||||
{
|
|
||||||
Audience = audience,
|
|
||||||
Claims = subject.Claims,
|
|
||||||
Expires = expires,
|
|
||||||
IssuedAt = issuedAt,
|
|
||||||
Issuer = issuer,
|
|
||||||
NotBefore = notBefore,
|
|
||||||
SigningCredentials = signingCredentials
|
|
||||||
};
|
|
||||||
var token = base.CreateToken(tokenDescriptor);
|
|
||||||
return token as JwtSecurityToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
using Microsoft.AspNet.Builder;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Api
|
|
||||||
{
|
|
||||||
public class RequiredScopesMiddleware
|
|
||||||
{
|
|
||||||
private readonly RequestDelegate _next;
|
|
||||||
private readonly IEnumerable<string> _requiredScopes;
|
|
||||||
|
|
||||||
public RequiredScopesMiddleware(RequestDelegate next, IList<string> requiredScopes)
|
|
||||||
{
|
|
||||||
_next = next;
|
|
||||||
_requiredScopes = requiredScopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
|
||||||
{
|
|
||||||
if (context.User.Identity.IsAuthenticated)
|
|
||||||
{
|
|
||||||
if (!ScopePresent(context.User))
|
|
||||||
{
|
|
||||||
context.Response.OnCompleted(Send403, context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await _next(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ScopePresent(ClaimsPrincipal principal)
|
|
||||||
{
|
|
||||||
foreach (var scope in principal.FindAll("scope"))
|
|
||||||
{
|
|
||||||
if (_requiredScopes.Contains(scope.Value))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task Send403(object contextObject)
|
|
||||||
{
|
|
||||||
var context = contextObject as HttpContext;
|
|
||||||
context.Response.StatusCode = 403;
|
|
||||||
|
|
||||||
return Task.FromResult(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.DataProtection;
|
|
||||||
using Microsoft.AspNet.Identity;
|
|
||||||
using Yavsc.Models;
|
|
||||||
using Yavsc.Server;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth {
|
|
||||||
|
|
||||||
public class UserTokenProvider : Microsoft.AspNet.Identity.IUserTokenProvider<ApplicationUser>
|
|
||||||
{
|
|
||||||
public Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<ApplicationUser> manager, ApplicationUser user)
|
|
||||||
{
|
|
||||||
return Task.FromResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser> manager, ApplicationUser user)
|
|
||||||
{
|
|
||||||
if ( user==null ) throw new InvalidOperationException("no user");
|
|
||||||
var por = new MonoDataProtector(ServerConstants.ApplicationName, new string[] { purpose } );
|
|
||||||
|
|
||||||
return Task.FromResult(por.Protect(UserStamp(user)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<bool> ValidateAsync(string purpose, string token, UserManager<ApplicationUser> manager, ApplicationUser user)
|
|
||||||
{
|
|
||||||
var por = new MonoDataProtector(ServerConstants.ApplicationName,new string[] { purpose } );
|
|
||||||
var userStamp = por.Unprotect(token);
|
|
||||||
Console.WriteLine ("Unprotected: "+userStamp);
|
|
||||||
string [] values = userStamp.Split(';');
|
|
||||||
return Task.FromResult ( user.Id == values[0] && user.Email == values[1] && user.UserName == values[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string UserStamp(ApplicationUser user) {
|
|
||||||
return $"{user.Id};{user.Email};{user.UserName}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Microsoft.AspNet.DataProtection.XmlEncryption;
|
|
||||||
|
|
||||||
namespace Yavsc.Auth {
|
|
||||||
|
|
||||||
public class MonoXmlEncryptor : IXmlEncryptor
|
|
||||||
{
|
|
||||||
public MonoXmlEncryptor ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public EncryptedXmlInfo Encrypt(XElement plaintextElement)
|
|
||||||
{
|
|
||||||
var result = new EncryptedXmlInfo(plaintextElement,
|
|
||||||
typeof(MonoDataProtector));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue