oauth
This commit is contained in:
parent
989df49cf2
commit
19b41ed9f4
19 changed files with 1729 additions and 7620 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
|
using System;
|
||||||
using System.IdentityModel.Tokens;
|
using System.IdentityModel.Tokens;
|
||||||
|
|
||||||
namespace Yavsc
|
namespace Yavsc
|
||||||
{
|
{
|
||||||
|
[Obsolete("Use OAuth2AppSettings instead")]
|
||||||
public class TokenAuthOptions
|
public class TokenAuthOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,17 @@ namespace Yavsc
|
||||||
{
|
{
|
||||||
using Yavsc.Models.Auth;
|
using Yavsc.Models.Auth;
|
||||||
|
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const string RememberMeCookieName = "Berme";
|
public const string AccessDeniedPath = "~/forbidden";
|
||||||
|
public const string AuthorizePath = "~/authorize";
|
||||||
|
public const string TokenPath = "~/token";
|
||||||
|
public const string LoginPath = "~/signin";
|
||||||
|
public const string LogoutPath = "~/signout";
|
||||||
|
public const string MePath = "~/api/Me";
|
||||||
|
|
||||||
|
public const string ExternalAuthenticationSheme = "External";
|
||||||
|
public const string ApplicationAuthenticationSheme = "Server";
|
||||||
public static readonly Scope[] SiteScopes = {
|
public static readonly Scope[] SiteScopes = {
|
||||||
new Scope { Id = "profile", Description = "Your profile informations" },
|
new Scope { Id = "profile", Description = "Your profile informations" },
|
||||||
new Scope { Id = "book" , Description ="Your booking interface"},
|
new Scope { Id = "book" , Description ="Your booking interface"},
|
||||||
|
|
@ -40,8 +48,6 @@ namespace Yavsc
|
||||||
|
|
||||||
public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9 ]*$";
|
public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9 ]*$";
|
||||||
|
|
||||||
public const string AuthenticationEndPath = "/signin";
|
|
||||||
public const string TokenEndPath = "/token";
|
|
||||||
|
|
||||||
public const string KeyProtectorPurpose = "OAuth.AspNet.AuthServer";
|
public const string KeyProtectorPurpose = "OAuth.AspNet.AuthServer";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,18 +50,62 @@ namespace Yavsc.Controllers
|
||||||
_twilioSettings = twilioSettings.Value;
|
_twilioSettings = twilioSettings.Value;
|
||||||
_logger = loggerFactory.CreateLogger<AccountController>();
|
_logger = loggerFactory.CreateLogger<AccountController>();
|
||||||
}
|
}
|
||||||
|
[HttpGet(Constants.LoginPath)]
|
||||||
[HttpGet("~/login")]
|
public ActionResult Login(string returnUrl = null)
|
||||||
public IActionResult Login(string returnUrl)
|
|
||||||
{
|
{
|
||||||
return View("SignIn", new LoginViewModel {
|
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
||||||
|
// will be redirected to after a successful authentication and not
|
||||||
|
// the redirect_uri of the requesting client application against the third
|
||||||
|
// party identity provider.
|
||||||
|
return View("Login", new LoginViewModel
|
||||||
|
{
|
||||||
ReturnUrl = returnUrl,
|
ReturnUrl = returnUrl,
|
||||||
ExternalProviders = HttpContext.GetExternalProviders()
|
ExternalProviders = HttpContext.GetExternalProviders()
|
||||||
});
|
});
|
||||||
|
/* Note: When using an external login provider, redirect the query :
|
||||||
|
var properties = _signInManager.ConfigureExternalAuthenticationProperties(OpenIdConnectDefaults.AuthenticationScheme, returnUrl);
|
||||||
|
return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, properties);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("~/login")]
|
|
||||||
public async Task<IActionResult> SignIn(LoginViewModel model)
|
public IActionResult ExternalLogin(string Provider, string ReturnUrl)
|
||||||
|
{
|
||||||
|
// Note: the "provider" parameter corresponds to the external
|
||||||
|
// authentication provider choosen by the user agent.
|
||||||
|
if (string.IsNullOrEmpty(Provider))
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Provider not specified");
|
||||||
|
return HttpBadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_signInManager.GetExternalAuthenticationSchemes().Any(x => x.AuthenticationScheme == Provider))
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"Provider not found : {Provider}");
|
||||||
|
return HttpBadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instruct the middleware corresponding to the requested external identity
|
||||||
|
// provider to redirect the user agent to its own authorization endpoint.
|
||||||
|
// Note: the authenticationScheme parameter must match the value configured in Startup.cs
|
||||||
|
|
||||||
|
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
||||||
|
// will be redirected to after a successful authentication and not
|
||||||
|
// the redirect_uri of the requesting client application.
|
||||||
|
if (string.IsNullOrEmpty(ReturnUrl))
|
||||||
|
{
|
||||||
|
_logger.LogWarning("ReturnUrl not specified");
|
||||||
|
return HttpBadRequest();
|
||||||
|
}
|
||||||
|
// Note: this still is not the redirect uri given to the third party provider, at building the challenge.
|
||||||
|
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = ReturnUrl });
|
||||||
|
var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, redirectUrl);
|
||||||
|
// var properties = new AuthenticationProperties{RedirectUri=ReturnUrl};
|
||||||
|
return new ChallengeResult(Provider, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost(Constants.LoginPath)]
|
||||||
|
public async Task<IActionResult> Login(LoginViewModel model)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -92,6 +136,7 @@ namespace Yavsc.Controllers
|
||||||
ModelState.AddModelError(string.Empty, "Unexpected behavior: something failed ... you could try again, or contact me ...");
|
ModelState.AddModelError(string.Empty, "Unexpected behavior: something failed ... you could try again, or contact me ...");
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// GET: /Account/Register
|
// GET: /Account/Register
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
|
@ -131,7 +176,7 @@ namespace Yavsc.Controllers
|
||||||
|
|
||||||
//
|
//
|
||||||
// POST: /Account/LogOff
|
// POST: /Account/LogOff
|
||||||
[HttpPost]
|
[HttpPost(Constants.LogoutPath)]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public async Task<IActionResult> LogOff(string returnUrl = null)
|
public async Task<IActionResult> LogOff(string returnUrl = null)
|
||||||
{
|
{
|
||||||
|
|
@ -140,18 +185,6 @@ namespace Yavsc.Controllers
|
||||||
if (returnUrl==null) return RedirectToAction(nameof(HomeController.Index), "Home");
|
if (returnUrl==null) return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||||
return Redirect(returnUrl);
|
return Redirect(returnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// POST: /Account/ExternalLogin
|
|
||||||
[HttpPost]
|
|
||||||
[ValidateAntiForgeryToken]
|
|
||||||
public IActionResult ExternalLogin(string provider, string returnUrl = null)
|
|
||||||
{
|
|
||||||
// Request a redirect to the external login provider.
|
|
||||||
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
|
|
||||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
|
|
||||||
return new ChallengeResult(provider, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// GET: /Account/ExternalLoginCallback
|
// GET: /Account/ExternalLoginCallback
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,40 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Authorization;
|
using Microsoft.AspNet.Authorization;
|
||||||
using Microsoft.AspNet.DataProtection.KeyManagement;
|
using Microsoft.AspNet.DataProtection.KeyManagement;
|
||||||
|
using Microsoft.AspNet.Http.Authentication;
|
||||||
using Microsoft.AspNet.Identity;
|
using Microsoft.AspNet.Identity;
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.Data.Entity;
|
using Microsoft.AspNet.WebUtilities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.OptionsModel;
|
using Microsoft.Extensions.OptionsModel;
|
||||||
using Yavsc.Extensions;
|
using OAuth.AspNet.AuthServer;
|
||||||
using Yavsc.Models;
|
using Yavsc.Models;
|
||||||
using Yavsc.ViewModels.Account;
|
|
||||||
|
|
||||||
namespace Yavsc.Controllers
|
namespace Yavsc.Controllers
|
||||||
{
|
{
|
||||||
|
public class TokenResponse
|
||||||
|
{
|
||||||
|
public string access_token { get; set; }
|
||||||
|
public int expires_in { get; set; }
|
||||||
|
public string grant_type { get; set; }
|
||||||
|
|
||||||
|
public int entity_id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public class OAuthController : Controller
|
public class OAuthController : Controller
|
||||||
{
|
{
|
||||||
ApplicationDbContext _context;
|
ApplicationDbContext _context;
|
||||||
UserManager<ApplicationUser> _userManager;
|
UserManager<ApplicationUser> _userManager;
|
||||||
|
|
||||||
SiteSettings _siteSettings;
|
SiteSettings _siteSettings;
|
||||||
|
|
||||||
ILogger _logger;
|
ILogger _logger;
|
||||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||||
private TokenAuthOptions _tokenOptions;
|
|
||||||
|
|
||||||
public OAuthController(ApplicationDbContext context, SignInManager<ApplicationUser> signInManager, IKeyManager keyManager,
|
public OAuthController(ApplicationDbContext context, SignInManager<ApplicationUser> signInManager, IKeyManager keyManager,
|
||||||
IOptions<TokenAuthOptions> tokenOptions,
|
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
IOptions<SiteSettings> siteSettings,
|
IOptions<SiteSettings> siteSettings,
|
||||||
ILoggerFactory loggerFactory
|
ILoggerFactory loggerFactory
|
||||||
|
|
@ -37,90 +43,61 @@ namespace Yavsc.Controllers
|
||||||
_siteSettings = siteSettings.Value;
|
_siteSettings = siteSettings.Value;
|
||||||
_context = context;
|
_context = context;
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
_tokenOptions = tokenOptions.Value;
|
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_logger = loggerFactory.CreateLogger<OAuthController>();
|
_logger = loggerFactory.CreateLogger<OAuthController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("~/signin")]
|
|
||||||
public ActionResult SignIn(string returnUrl = null)
|
|
||||||
{
|
|
||||||
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
|
||||||
// will be redirected to after a successful authentication and not
|
|
||||||
// the redirect_uri of the requesting client application against the third
|
|
||||||
// party identity provider.
|
|
||||||
return View("SignIn", new LoginViewModel
|
|
||||||
{
|
|
||||||
ReturnUrl = returnUrl,
|
|
||||||
ExternalProviders = HttpContext.GetExternalProviders()
|
|
||||||
});
|
|
||||||
/* Note: When using an external login provider, redirect the query :
|
|
||||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(OpenIdConnectDefaults.AuthenticationScheme, returnUrl);
|
|
||||||
return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, properties);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("~/authenticate")]
|
|
||||||
public ActionResult Authenticate(string returnUrl = null)
|
|
||||||
{
|
|
||||||
return SignIn(returnUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("~/forbidden")]
|
|
||||||
|
[HttpGet(Constants.AccessDeniedPath)]
|
||||||
public ActionResult Forbidden(string returnUrl = null)
|
public ActionResult Forbidden(string returnUrl = null)
|
||||||
{
|
{
|
||||||
return View("Forbidden",returnUrl);
|
return View("Forbidden", returnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("~/signin")]
|
/*
|
||||||
public IActionResult SignIn(string Provider, string ReturnUrl)
|
private async Task<string> GetToken(string purpose, string userid, DateTime? expires)
|
||||||
{
|
{
|
||||||
// Note: the "provider" parameter corresponds to the external
|
// Here, you should create or look up an identity for the user which is being authenticated.
|
||||||
// authentication provider choosen by the user agent.
|
// For now, just creating a simple generic identity.
|
||||||
if (string.IsNullOrEmpty(Provider))
|
var identuser = await _userManager.FindByIdAsync(userid);
|
||||||
{
|
|
||||||
_logger.LogWarning("Provider not specified");
|
|
||||||
return HttpBadRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_signInManager.GetExternalAuthenticationSchemes().Any(x => x.AuthenticationScheme == Provider))
|
return await _tokenProvider.GenerateAsync(purpose, _userManager, identuser);
|
||||||
{
|
|
||||||
_logger.LogWarning($"Provider not found : {Provider}");
|
|
||||||
return HttpBadRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instruct the middleware corresponding to the requested external identity
|
|
||||||
// provider to redirect the user agent to its own authorization endpoint.
|
|
||||||
// Note: the authenticationScheme parameter must match the value configured in Startup.cs
|
|
||||||
|
|
||||||
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
|
||||||
// will be redirected to after a successful authentication and not
|
|
||||||
// the redirect_uri of the requesting client application.
|
|
||||||
if (string.IsNullOrEmpty(ReturnUrl))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("ReturnUrl not specified");
|
|
||||||
return HttpBadRequest();
|
|
||||||
}
|
|
||||||
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = ReturnUrl });
|
|
||||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, redirectUrl);
|
|
||||||
// var properties = new AuthenticationProperties{RedirectUri=ReturnUrl};
|
|
||||||
return new ChallengeResult(Provider,properties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if currently authenticated. Will throw an exception of some sort which shoudl be caught by a general
|
||||||
[HttpGet("~/signout"), HttpPost("~/signout")]
|
/// exception handler and returned to the user as a 401, if not authenticated. Will return a fresh token if
|
||||||
public async Task SignOut()
|
/// the user is authenticated, which will reset the expiry.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet, HttpPost, Authorize]
|
||||||
|
[Route("~/oauth/token")]
|
||||||
|
public async Task<dynamic> Get()
|
||||||
{
|
{
|
||||||
// Instruct the cookies middleware to delete the local cookie created
|
bool authenticated = false;
|
||||||
// when the user agent is redirected from the external identity provider
|
string user = null;
|
||||||
// after a successful authentication flow (e.g Google or Facebook).
|
int entityId = -1;
|
||||||
|
string token = null;
|
||||||
await HttpContext.Authentication.SignOutAsync("ServerCookie");
|
DateTime? tokenExpires = default(DateTime?);
|
||||||
}
|
var currentUser = User;
|
||||||
|
if (currentUser != null)
|
||||||
|
{
|
||||||
|
authenticated = currentUser.Identity.IsAuthenticated;
|
||||||
|
if (authenticated)
|
||||||
|
{
|
||||||
|
user = User.GetUserId();
|
||||||
|
_logger.LogInformation($"authenticated user:{user}");
|
||||||
|
|
||||||
|
foreach (Claim c in currentUser.Claims) if (c.Type == "EntityID") entityId = Convert.ToInt32(c.Value);
|
||||||
|
|
||||||
|
tokenExpires = DateTime.UtcNow.AddMinutes(2);
|
||||||
|
token = await GetToken("id_token", user, tokenExpires);
|
||||||
|
return new TokenResponse { access_token = token, expires_in = 3400, entity_id = entityId };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new { authenticated = false };
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("~/api/getclaims"), Produces("application/json")]
|
[HttpGet("~/api/getclaims"), Produces("application/json")]
|
||||||
|
|
@ -140,14 +117,66 @@ namespace Yavsc.Controllers
|
||||||
return Ok(claims);
|
return Ok(claims);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Task<Application> GetApplicationAsync(string identifier, CancellationToken cancellationToken)
|
[HttpGet(Constants.AuthorizePath)]
|
||||||
|
public async Task<ActionResult> Authorize()
|
||||||
{
|
{
|
||||||
// Retrieve the application details corresponding to the requested client_id.
|
if (Response.StatusCode != 200)
|
||||||
return (from application in _context.Applications
|
{
|
||||||
where application.ApplicationID == identifier
|
return View("AuthorizeError");
|
||||||
select application).SingleOrDefaultAsync(cancellationToken);
|
}
|
||||||
|
|
||||||
|
AuthenticationManager authentication = Request.HttpContext.Authentication;
|
||||||
|
|
||||||
|
ClaimsPrincipal principal = await authentication.AuthenticateAsync(Constants.ApplicationAuthenticationSheme);
|
||||||
|
|
||||||
|
if (principal == null)
|
||||||
|
{
|
||||||
|
await authentication.ChallengeAsync(Constants.ApplicationAuthenticationSheme);
|
||||||
|
|
||||||
|
if (Response.StatusCode == 200)
|
||||||
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
|
return new HttpStatusCodeResult(Response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] scopes = { };
|
||||||
|
|
||||||
|
if (Request.QueryString.HasValue)
|
||||||
|
{
|
||||||
|
var queryStringComponents = QueryHelpers.ParseQuery(Request.QueryString.Value);
|
||||||
|
|
||||||
|
if (queryStringComponents.ContainsKey("scope"))
|
||||||
|
scopes = queryStringComponents["scope"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Request.Method == "POST")
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Request.Form["submit.Grant"]))
|
||||||
|
{
|
||||||
|
principal = new ClaimsPrincipal(principal.Identities);
|
||||||
|
|
||||||
|
ClaimsIdentity primaryIdentity = (ClaimsIdentity)principal.Identity;
|
||||||
|
|
||||||
|
foreach (var scope in scopes)
|
||||||
|
{
|
||||||
|
primaryIdentity.AddClaim(new Claim("urn:oauth:scope", scope));
|
||||||
|
}
|
||||||
|
|
||||||
|
await authentication.SignInAsync(OAuthDefaults.AuthenticationType, principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Request.Form["submit.Login"]))
|
||||||
|
{
|
||||||
|
await authentication.SignOutAsync(Constants.ApplicationAuthenticationSheme);
|
||||||
|
|
||||||
|
await authentication.ChallengeAsync(Constants.ApplicationAuthenticationSheme);
|
||||||
|
|
||||||
|
return new HttpUnauthorizedResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return View(new AuthorisationView { Scopes = scopes } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Mvc;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNet.Authorization;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.OptionsModel;
|
|
||||||
using Yavsc.Auth;
|
|
||||||
using Microsoft.AspNet.Identity;
|
|
||||||
using Yavsc.Models;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yavsc.Controllers
|
|
||||||
{
|
|
||||||
[Produces("application/json"),AllowAnonymous]
|
|
||||||
public class TokenController : Controller
|
|
||||||
{
|
|
||||||
private readonly TokenAuthOptions tokenOptions;
|
|
||||||
private ILogger logger;
|
|
||||||
UserManager<ApplicationUser> manager;
|
|
||||||
SignInManager<ApplicationUser> signInManager;
|
|
||||||
public class TokenResponse {
|
|
||||||
public string access_token { get; set; }
|
|
||||||
public int expires_in { get; set; }
|
|
||||||
public string grant_type { get; set; }
|
|
||||||
|
|
||||||
public int entity_id { get; set; }
|
|
||||||
}
|
|
||||||
UserTokenProvider tokenProvider;
|
|
||||||
|
|
||||||
public TokenController( UserManager<ApplicationUser> userManager,
|
|
||||||
SignInManager<ApplicationUser> signInManager,
|
|
||||||
IOptions<TokenAuthOptions> token_options, ILoggerFactory loggerFactory, UserTokenProvider tokenProvider)
|
|
||||||
{
|
|
||||||
this.manager = userManager;
|
|
||||||
this.tokenOptions = token_options.Value;
|
|
||||||
this.signInManager = signInManager;
|
|
||||||
this.tokenProvider = tokenProvider;
|
|
||||||
//this.bearerOptions = options.Value;
|
|
||||||
//this.signingCredentials = signingCredentials;
|
|
||||||
logger = loggerFactory.CreateLogger<TokenController>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if currently authenticated. Will throw an exception of some sort which shoudl be caught by a general
|
|
||||||
/// exception handler and returned to the user as a 401, if not authenticated. Will return a fresh token if
|
|
||||||
/// the user is authenticated, which will reset the expiry.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet,HttpPost,Authorize]
|
|
||||||
[Route("~/api/token/get")]
|
|
||||||
public async Task<dynamic> Get()
|
|
||||||
{
|
|
||||||
bool authenticated = false;
|
|
||||||
string user = null;
|
|
||||||
int entityId = -1;
|
|
||||||
string token = null;
|
|
||||||
DateTime? tokenExpires = default(DateTime?);
|
|
||||||
var currentUser = User;
|
|
||||||
if (currentUser != null)
|
|
||||||
{
|
|
||||||
authenticated = currentUser.Identity.IsAuthenticated;
|
|
||||||
if (authenticated)
|
|
||||||
{
|
|
||||||
user = User.GetUserId();
|
|
||||||
logger.LogInformation($"authenticated user:{user}");
|
|
||||||
|
|
||||||
foreach (Claim c in currentUser.Claims) if (c.Type == "EntityID") entityId = Convert.ToInt32(c.Value);
|
|
||||||
|
|
||||||
tokenExpires = DateTime.UtcNow.AddMinutes(2);
|
|
||||||
token = await GetToken("id_token", user, tokenExpires);
|
|
||||||
return new TokenResponse { access_token = token, expires_in = 3400, entity_id = entityId };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new { authenticated = false };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AuthRequest
|
|
||||||
{
|
|
||||||
public string username { get; set; }
|
|
||||||
public string password { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Request a new token for a given username/password pair.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="req"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPost,Route("~/api/token/post")]
|
|
||||||
public async Task<IActionResult> Post(AuthRequest req)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return new BadRequestObjectResult(ModelState);
|
|
||||||
// Obviously, at this point you need to validate the username and password against whatever system you wish.
|
|
||||||
var signResult = await signInManager.PasswordSignInAsync(req.username, req.password,false,true);
|
|
||||||
|
|
||||||
if (signResult.Succeeded)
|
|
||||||
{
|
|
||||||
DateTime? expires = DateTime.UtcNow.AddMinutes(tokenOptions.ExpiresIn);
|
|
||||||
var token = await GetToken("id_token",User.GetUserId(), expires);
|
|
||||||
return Ok(new TokenResponse {access_token = token, expires_in = 3400, grant_type="id_token" });
|
|
||||||
}
|
|
||||||
return new BadRequestObjectResult(new { authenticated = false } ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> GetToken(string purpose, string userid, DateTime? expires)
|
|
||||||
{
|
|
||||||
// Here, you should create or look up an identity for the user which is being authenticated.
|
|
||||||
// For now, just creating a simple generic identity.
|
|
||||||
var identuser = await manager.FindByIdAsync(userid);
|
|
||||||
|
|
||||||
return await tokenProvider.GenerateAsync(purpose,manager,identuser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
41
Yavsc/Startup/Startup.DataProtection.cs
Normal file
41
Yavsc/Startup/Startup.DataProtection.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using Microsoft.AspNet.DataProtection.Infrastructure;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Yavsc
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class Startup
|
||||||
|
{
|
||||||
|
public void ConfigureProtectionServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
|
||||||
|
services.AddDataProtection();
|
||||||
|
services.Add(ServiceDescriptor.Singleton(typeof(IApplicationDiscriminator),
|
||||||
|
typeof(SystemWebApplicationDiscriminator)));
|
||||||
|
|
||||||
|
services.ConfigureDataProtection(configure =>
|
||||||
|
{
|
||||||
|
configure.SetApplicationName(Configuration["Site:Title"]);
|
||||||
|
configure.SetDefaultKeyLifetime(TimeSpan.FromDays(45));
|
||||||
|
configure.PersistKeysToFileSystem(
|
||||||
|
new DirectoryInfo(Configuration["DataProtection:Keys:Dir"]));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
private sealed class SystemWebApplicationDiscriminator : IApplicationDiscriminator
|
||||||
|
{
|
||||||
|
private readonly Lazy<string> _lazyDiscriminator = new Lazy<string>(GetAppDiscriminatorCore);
|
||||||
|
|
||||||
|
public string Discriminator => _lazyDiscriminator.Value;
|
||||||
|
|
||||||
|
private static string GetAppDiscriminatorCore()
|
||||||
|
{
|
||||||
|
return HttpRuntime.AppDomainAppId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
174
Yavsc/Startup/Startup.OAuth.cs
Normal file
174
Yavsc/Startup/Startup.OAuth.cs
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
using System;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.Authentication;
|
||||||
|
using Microsoft.AspNet.Authentication.OAuth;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.OptionsModel;
|
||||||
|
using Microsoft.Extensions.WebEncoders;
|
||||||
|
using OAuth.AspNet.AuthServer;
|
||||||
|
using Yavsc.Auth;
|
||||||
|
using Yavsc.Models;
|
||||||
|
|
||||||
|
namespace Yavsc
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class Startup
|
||||||
|
{
|
||||||
|
private void ConfigureOAuthServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Configure<SharedAuthenticationOptions>(options => options.SignInScheme = Constants.ExternalAuthenticationSheme);
|
||||||
|
services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.SignInScheme = Constants.ExternalAuthenticationSheme;
|
||||||
|
});
|
||||||
|
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<OAuth2AppSettings>), typeof(OptionsManager<OAuth2AppSettings>)));
|
||||||
|
// used by the YavscGoogleOAuth middelware (TODO drop it)
|
||||||
|
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
|
||||||
|
/* Obsolete:
|
||||||
|
var keyParamsFileInfo =
|
||||||
|
new FileInfo(Configuration["DataProtection:RSAParamFile"]);
|
||||||
|
var keyParams = (keyParamsFileInfo.Exists) ?
|
||||||
|
RSAKeyUtils.GetKeyParameters(keyParamsFileInfo.Name) :
|
||||||
|
RSAKeyUtils.GenerateKeyAndSave(keyParamsFileInfo.Name);
|
||||||
|
key = new RsaSecurityKey(keyParams);
|
||||||
|
|
||||||
|
services.Configure<TokenAuthOptions>(
|
||||||
|
to =>
|
||||||
|
{
|
||||||
|
to.Audience = Configuration["Site:Audience"];
|
||||||
|
to.Issuer = Configuration["Site:Authority"];
|
||||||
|
to.SigningCredentials =
|
||||||
|
new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature);
|
||||||
|
}
|
||||||
|
); */
|
||||||
|
}
|
||||||
|
private void ConfigureOAuthApp(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.UseIdentity();
|
||||||
|
// External authentication shared cookie:
|
||||||
|
app.UseCookieAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.AuthenticationScheme = Constants.ExternalAuthenticationSheme;
|
||||||
|
options.AutomaticAuthenticate = false;
|
||||||
|
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
||||||
|
options.LoginPath = new PathString(Constants.LoginPath.Substring(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
var gvents = new OAuthEvents();
|
||||||
|
var googleOptions = new YavscGoogleOptions
|
||||||
|
{
|
||||||
|
ClientId = Configuration["Authentication:Google:ClientId"],
|
||||||
|
ClientSecret = Configuration["Authentication:Google:ClientSecret"],
|
||||||
|
AccessType = "offline",
|
||||||
|
SaveTokensAsClaims = true,
|
||||||
|
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me",
|
||||||
|
Events = new OAuthEvents
|
||||||
|
{
|
||||||
|
OnCreatingTicket = async context =>
|
||||||
|
{
|
||||||
|
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
|
||||||
|
.CreateScope())
|
||||||
|
{
|
||||||
|
var gcontext = context as GoogleOAuthCreatingTicketContext;
|
||||||
|
context.Identity.AddClaim(new Claim(YavscClaimTypes.GoogleUserId, gcontext.GoogleUserId));
|
||||||
|
var service =
|
||||||
|
serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
|
||||||
|
await service.StoreTokenAsync(gcontext.GoogleUserId, context.TokenResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
googleOptions.Scope.Add("https://www.googleapis.com/auth/calendar");
|
||||||
|
app.UseMiddleware<Yavsc.Auth.GoogleMiddleware>(googleOptions);
|
||||||
|
|
||||||
|
// Facebook
|
||||||
|
app.UseFacebookAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.AppId = Configuration["Authentication:Facebook:AppId"];
|
||||||
|
options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
|
||||||
|
options.Scope.Add("email");
|
||||||
|
options.UserInformationEndpoint = "https://graph.facebook.com/v2.5/me?fields=id,name,email,first_name,last_name";
|
||||||
|
});
|
||||||
|
/* Generic OAuth (here GitHub): options.Notifications = new OAuthAuthenticationNotifications
|
||||||
|
{
|
||||||
|
OnGetUserInformationAsync = async context =>
|
||||||
|
{
|
||||||
|
// Get the GitHub user
|
||||||
|
HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
|
||||||
|
userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
|
||||||
|
userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted);
|
||||||
|
userResponse.EnsureSuccessStatusCode();
|
||||||
|
var text = await userResponse.Content.ReadAsStringAsync();
|
||||||
|
JObject user = JObject.Parse(text);
|
||||||
|
|
||||||
|
var identity = new ClaimsIdentity(
|
||||||
|
context.Options.AuthenticationType,
|
||||||
|
ClaimsIdentity.DefaultNameClaimType,
|
||||||
|
ClaimsIdentity.DefaultRoleClaimType);
|
||||||
|
|
||||||
|
JToken value;
|
||||||
|
var id = user.TryGetValue("id", out value) ? value.ToString() : null;
|
||||||
|
if (!string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.AuthenticationType));
|
||||||
|
}
|
||||||
|
var userName = user.TryGetValue("login", out value) ? value.ToString() : null;
|
||||||
|
if (!string.IsNullOrEmpty(userName))
|
||||||
|
{
|
||||||
|
identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.AuthenticationType));
|
||||||
|
}
|
||||||
|
var name = user.TryGetValue("name", out value) ? value.ToString() : null;
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.AuthenticationType));
|
||||||
|
}
|
||||||
|
var link = user.TryGetValue("url", out value) ? value.ToString() : null;
|
||||||
|
if (!string.IsNullOrEmpty(link))
|
||||||
|
{
|
||||||
|
identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.AuthenticationType));
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Identity = identity;
|
||||||
|
}
|
||||||
|
}; */
|
||||||
|
app.UseOAuthAuthorizationServer(
|
||||||
|
|
||||||
|
options =>
|
||||||
|
{
|
||||||
|
options.AuthorizeEndpointPath = new PathString(Constants.AuthorizePath.Substring(1));
|
||||||
|
options.TokenEndpointPath = new PathString(Constants.TokenPath.Substring(1));
|
||||||
|
options.ApplicationCanDisplayErrors = true;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
options.AllowInsecureHttp = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
options.Provider = new OAuthAuthorizationServerProvider
|
||||||
|
{
|
||||||
|
OnValidateClientRedirectUri = ValidateClientRedirectUri,
|
||||||
|
OnValidateClientAuthentication = ValidateClientAuthentication,
|
||||||
|
OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
|
||||||
|
OnGrantClientCredentials = GrantClientCredetails
|
||||||
|
};
|
||||||
|
|
||||||
|
options.AuthorizationCodeProvider = new AuthenticationTokenProvider
|
||||||
|
{
|
||||||
|
OnCreate = CreateAuthenticationCode,
|
||||||
|
OnReceive = ReceiveAuthenticationCode,
|
||||||
|
};
|
||||||
|
|
||||||
|
options.RefreshTokenProvider = new AuthenticationTokenProvider
|
||||||
|
{
|
||||||
|
OnCreate = CreateRefreshToken,
|
||||||
|
OnReceive = ReceiveRefreshToken,
|
||||||
|
};
|
||||||
|
|
||||||
|
options.AutomaticAuthenticate = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IdentityModel.Tokens;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Web;
|
|
||||||
using System.Web.Optimization;
|
using System.Web.Optimization;
|
||||||
using Microsoft.AspNet.Authentication;
|
using Microsoft.AspNet.Authentication;
|
||||||
using Microsoft.AspNet.Authentication.OAuth;
|
|
||||||
using Microsoft.AspNet.Authorization;
|
using Microsoft.AspNet.Authorization;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.DataProtection.Infrastructure;
|
|
||||||
using Microsoft.AspNet.Diagnostics;
|
using Microsoft.AspNet.Diagnostics;
|
||||||
using Microsoft.AspNet.Hosting;
|
using Microsoft.AspNet.Hosting;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
|
@ -27,13 +21,11 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.OptionsModel;
|
using Microsoft.Extensions.OptionsModel;
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
using Microsoft.Extensions.PlatformAbstractions;
|
||||||
using Microsoft.Extensions.WebEncoders;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Yavsc.Auth;
|
using Yavsc.Auth;
|
||||||
using Yavsc.Formatters;
|
using Yavsc.Formatters;
|
||||||
using Yavsc.Models;
|
using Yavsc.Models;
|
||||||
using Yavsc.Services;
|
using Yavsc.Services;
|
||||||
using OAuth.AspNet.AuthServer;
|
|
||||||
|
|
||||||
namespace Yavsc
|
namespace Yavsc
|
||||||
{
|
{
|
||||||
|
|
@ -41,8 +33,6 @@ namespace Yavsc
|
||||||
public partial class Startup
|
public partial class Startup
|
||||||
{
|
{
|
||||||
public static string ConnectionString { get; private set; }
|
public static string ConnectionString { get; private set; }
|
||||||
private RsaSecurityKey key;
|
|
||||||
|
|
||||||
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
|
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
|
||||||
{
|
{
|
||||||
// Set up configuration sources.
|
// Set up configuration sources.
|
||||||
|
|
@ -97,7 +87,6 @@ namespace Yavsc
|
||||||
new CultureInfo("fr")
|
new CultureInfo("fr")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// You must explicitly state which cultures your application supports.
|
// You must explicitly state which cultures your application supports.
|
||||||
// These are the cultures the app supports for formatting numbers, dates, etc.
|
// These are the cultures the app supports for formatting numbers, dates, etc.
|
||||||
options.SupportedCultures = supportedCultures;
|
options.SupportedCultures = supportedCultures;
|
||||||
|
|
@ -118,54 +107,17 @@ namespace Yavsc
|
||||||
// return new ProviderCultureResult("en");
|
// return new ProviderCultureResult("en");
|
||||||
//}));
|
//}));
|
||||||
});
|
});
|
||||||
var keyParamsFileInfo =
|
|
||||||
new FileInfo(Configuration["DataProtection:RSAParamFile"]);
|
|
||||||
var keyParams = (keyParamsFileInfo.Exists) ?
|
|
||||||
RSAKeyUtils.GetKeyParameters(keyParamsFileInfo.Name) :
|
|
||||||
RSAKeyUtils.GenerateKeyAndSave(keyParamsFileInfo.Name);
|
|
||||||
key = new RsaSecurityKey(keyParams);
|
|
||||||
|
|
||||||
services.Configure<SharedAuthenticationOptions>(options =>
|
|
||||||
{
|
|
||||||
options.SignInScheme = "ServerCookie";
|
|
||||||
});
|
|
||||||
|
|
||||||
services.Configure<TokenAuthOptions>(
|
|
||||||
to =>
|
|
||||||
{
|
|
||||||
to.Audience = Configuration["Site:Audience"];
|
|
||||||
to.Issuer = Configuration["Site:Authority"];
|
|
||||||
to.SigningCredentials =
|
|
||||||
new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
ConfigureOAuthServices(services);
|
||||||
|
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SiteSettings>), typeof(OptionsManager<SiteSettings>)));
|
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SiteSettings>), typeof(OptionsManager<SiteSettings>)));
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SmtpSettings>), typeof(OptionsManager<SmtpSettings>)));
|
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SmtpSettings>), typeof(OptionsManager<SmtpSettings>)));
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<GoogleAuthSettings>), typeof(OptionsManager<GoogleAuthSettings>)));
|
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<GoogleAuthSettings>), typeof(OptionsManager<GoogleAuthSettings>)));
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<CompanyInfoSettings>), typeof(OptionsManager<CompanyInfoSettings>)));
|
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<CompanyInfoSettings>), typeof(OptionsManager<CompanyInfoSettings>)));
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<OAuth2AppSettings>), typeof(OptionsManager<OAuth2AppSettings>)));
|
|
||||||
|
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<TokenAuthOptions>), typeof(OptionsManager<TokenAuthOptions>)));
|
// DataProtection
|
||||||
|
ConfigureProtectionServices(services);
|
||||||
|
|
||||||
|
|
||||||
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
|
|
||||||
services.AddDataProtection();
|
|
||||||
services.Add(ServiceDescriptor.Singleton(typeof(IApplicationDiscriminator),
|
|
||||||
typeof(SystemWebApplicationDiscriminator)));
|
|
||||||
|
|
||||||
services.ConfigureDataProtection(configure =>
|
|
||||||
{
|
|
||||||
configure.SetApplicationName(Configuration["Site:Title"]);
|
|
||||||
configure.SetDefaultKeyLifetime(TimeSpan.FromDays(45));
|
|
||||||
configure.PersistKeysToFileSystem(
|
|
||||||
new DirectoryInfo(Configuration["DataProtection:Keys:Dir"]));
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddAuthentication(
|
|
||||||
op => op.SignInScheme = "ServerCookie"
|
|
||||||
);
|
|
||||||
// Add framework services.
|
// Add framework services.
|
||||||
services.AddEntityFramework()
|
services.AddEntityFramework()
|
||||||
.AddNpgsql()
|
.AddNpgsql()
|
||||||
|
|
@ -179,6 +131,8 @@ namespace Yavsc
|
||||||
option.User.RequireUniqueEmail = true;
|
option.User.RequireUniqueEmail = true;
|
||||||
option.Cookies.ApplicationCookie.DataProtectionProvider =
|
option.Cookies.ApplicationCookie.DataProtectionProvider =
|
||||||
new MonoDataProtectionProvider(Configuration["Site:Title"]);
|
new MonoDataProtectionProvider(Configuration["Site:Title"]);
|
||||||
|
option.Cookies.ApplicationCookie.LoginPath = new PathString(Constants.LoginPath.Substring(1));
|
||||||
|
option.Cookies.ApplicationCookie.AccessDeniedPath = new PathString(Constants.AccessDeniedPath.Substring(1));
|
||||||
}
|
}
|
||||||
).AddEntityFrameworkStores<ApplicationDbContext>()
|
).AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.EMailFactor)
|
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.EMailFactor)
|
||||||
|
|
@ -331,181 +285,21 @@ namespace Yavsc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var googleOptions = new YavscGoogleOptions
|
|
||||||
{
|
|
||||||
ClientId = Configuration["Authentication:Google:ClientId"],
|
|
||||||
ClientSecret = Configuration["Authentication:Google:ClientSecret"],
|
|
||||||
AccessType = "offline",
|
|
||||||
SaveTokensAsClaims = true,
|
|
||||||
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me"
|
|
||||||
};
|
|
||||||
var gvents = new OAuthEvents();
|
|
||||||
|
|
||||||
googleOptions.Events = new OAuthEvents
|
|
||||||
{
|
|
||||||
OnCreatingTicket = async context =>
|
|
||||||
{
|
|
||||||
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
|
|
||||||
.CreateScope())
|
|
||||||
{
|
|
||||||
var gcontext = context as GoogleOAuthCreatingTicketContext;
|
|
||||||
context.Identity.AddClaim(new Claim(YavscClaimTypes.GoogleUserId, gcontext.GoogleUserId));
|
|
||||||
var service =
|
|
||||||
serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
|
|
||||||
await service.StoreTokenAsync(gcontext.GoogleUserId, context.TokenResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
googleOptions.Scope.Add("https://www.googleapis.com/auth/calendar");
|
|
||||||
|
|
||||||
app.UseIISPlatformHandler(options =>
|
app.UseIISPlatformHandler(options =>
|
||||||
{
|
{
|
||||||
options.AuthenticationDescriptions.Clear();
|
options.AuthenticationDescriptions.Clear();
|
||||||
options.AutomaticAuthentication = true;
|
options.AutomaticAuthentication = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ConfigureOAuthApp(app);
|
||||||
|
|
||||||
ConfigureFileServerApp(app,siteSettings.Value,env);
|
ConfigureFileServerApp(app,siteSettings.Value,env);
|
||||||
|
|
||||||
app.UseWebSockets();
|
app.UseWebSockets();
|
||||||
|
|
||||||
app.UseIdentity();
|
|
||||||
|
|
||||||
|
|
||||||
/* app.UseOpenIdConnectServer(options =>
|
|
||||||
{
|
|
||||||
options.Provider = new AuthorizationProvider(loggerFactory,
|
|
||||||
new UserTokenProvider());
|
|
||||||
|
|
||||||
// Register the certificate used to sign the JWT tokens.
|
|
||||||
// options.SigningCredentials.AddCertificate(
|
|
||||||
// assembly: typeof(Startup).GetTypeInfo().Assembly,
|
|
||||||
// resource: "Mvc.Server.Certificate.pfx",
|
|
||||||
// password: "Owin.Security.OpenIdConnect.Server");
|
|
||||||
|
|
||||||
// options.SigningCredentials.AddKey(key);
|
|
||||||
// Note: see AuthorizationController.cs for more
|
|
||||||
// information concerning ApplicationCanDisplayErrors.
|
|
||||||
options.ApplicationCanDisplayErrors = true;
|
|
||||||
options.AllowInsecureHttp = true;
|
|
||||||
options.AutomaticChallenge = true;
|
|
||||||
// options.AutomaticAuthenticate=true;
|
|
||||||
|
|
||||||
|
|
||||||
options.AuthorizationEndpointPath = new PathString("/connect/authorize");
|
|
||||||
options.TokenEndpointPath = new PathString("/connect/authorize/accept");
|
|
||||||
options.UseSlidingExpiration = true;
|
|
||||||
options.AllowInsecureHttp = true;
|
|
||||||
options.AuthenticationScheme = "oidc-server"; // was = OpenIdConnectDefaults.AuthenticationScheme || "oidc";
|
|
||||||
options.LogoutEndpointPath = new PathString("/connect/logout");
|
|
||||||
|
|
||||||
// options.ValidationEndpointPath = new PathString("/connect/introspect");
|
|
||||||
}); */
|
|
||||||
|
|
||||||
app.UseCookieAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.AutomaticAuthenticate = true;
|
|
||||||
options.AutomaticChallenge = true;
|
|
||||||
options.AuthenticationScheme = "ServerCookie";
|
|
||||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
|
||||||
options.LoginPath = new PathString("/signin");
|
|
||||||
options.LogoutPath = new PathString("/signout");
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseMiddleware<Yavsc.Auth.GoogleMiddleware>(googleOptions);
|
|
||||||
|
|
||||||
// Facebook
|
|
||||||
app.UseFacebookAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.AppId = Configuration["Authentication:Facebook:AppId"];
|
|
||||||
options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
|
|
||||||
options.Scope.Add("email");
|
|
||||||
options.UserInformationEndpoint = "https://graph.facebook.com/v2.5/me?fields=id,name,email,first_name,last_name";
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseOAuthAuthorizationServer(
|
|
||||||
|
|
||||||
options =>
|
|
||||||
{
|
|
||||||
options.AuthorizeEndpointPath = new PathString("/signin");
|
|
||||||
options.TokenEndpointPath = new PathString("/token");
|
|
||||||
options.ApplicationCanDisplayErrors = true;
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
options.AllowInsecureHttp = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
options.Provider = new OAuthAuthorizationServerProvider
|
|
||||||
{
|
|
||||||
OnValidateClientRedirectUri = ValidateClientRedirectUri,
|
|
||||||
OnValidateClientAuthentication = ValidateClientAuthentication,
|
|
||||||
OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials,
|
|
||||||
OnGrantClientCredentials = GrantClientCredetails
|
|
||||||
};
|
|
||||||
|
|
||||||
options.AuthorizationCodeProvider = new AuthenticationTokenProvider
|
|
||||||
{
|
|
||||||
OnCreate = CreateAuthenticationCode,
|
|
||||||
OnReceive = ReceiveAuthenticationCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
options.RefreshTokenProvider = new AuthenticationTokenProvider
|
|
||||||
{
|
|
||||||
OnCreate = CreateRefreshToken,
|
|
||||||
OnReceive = ReceiveRefreshToken,
|
|
||||||
};
|
|
||||||
|
|
||||||
options.AutomaticAuthenticate = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"fr"));
|
app.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"fr"));
|
||||||
|
|
||||||
/* Generic OAuth (here GitHub): options.Notifications = new OAuthAuthenticationNotifications
|
|
||||||
{
|
|
||||||
OnGetUserInformationAsync = async context =>
|
|
||||||
{
|
|
||||||
// Get the GitHub user
|
|
||||||
HttpRequestMessage userRequest = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
|
|
||||||
userRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
|
|
||||||
userRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
|
||||||
HttpResponseMessage userResponse = await context.Backchannel.SendAsync(userRequest, context.HttpContext.RequestAborted);
|
|
||||||
userResponse.EnsureSuccessStatusCode();
|
|
||||||
var text = await userResponse.Content.ReadAsStringAsync();
|
|
||||||
JObject user = JObject.Parse(text);
|
|
||||||
|
|
||||||
var identity = new ClaimsIdentity(
|
|
||||||
context.Options.AuthenticationType,
|
|
||||||
ClaimsIdentity.DefaultNameClaimType,
|
|
||||||
ClaimsIdentity.DefaultRoleClaimType);
|
|
||||||
|
|
||||||
JToken value;
|
|
||||||
var id = user.TryGetValue("id", out value) ? value.ToString() : null;
|
|
||||||
if (!string.IsNullOrEmpty(id))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id, ClaimValueTypes.String, context.Options.AuthenticationType));
|
|
||||||
}
|
|
||||||
var userName = user.TryGetValue("login", out value) ? value.ToString() : null;
|
|
||||||
if (!string.IsNullOrEmpty(userName))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, userName, ClaimValueTypes.String, context.Options.AuthenticationType));
|
|
||||||
}
|
|
||||||
var name = user.TryGetValue("name", out value) ? value.ToString() : null;
|
|
||||||
if (!string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim("urn:github:name", name, ClaimValueTypes.String, context.Options.AuthenticationType));
|
|
||||||
}
|
|
||||||
var link = user.TryGetValue("url", out value) ? value.ToString() : null;
|
|
||||||
if (!string.IsNullOrEmpty(link))
|
|
||||||
{
|
|
||||||
identity.AddClaim(new Claim("urn:github:url", link, ClaimValueTypes.String, context.Options.AuthenticationType));
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Identity = identity;
|
|
||||||
}
|
|
||||||
}; */
|
|
||||||
|
|
||||||
|
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
{
|
{
|
||||||
routes.MapRoute(
|
routes.MapRoute(
|
||||||
|
|
@ -515,17 +309,7 @@ namespace Yavsc
|
||||||
|
|
||||||
app.UseSignalR();
|
app.UseSignalR();
|
||||||
}
|
}
|
||||||
private sealed class SystemWebApplicationDiscriminator : IApplicationDiscriminator
|
|
||||||
{
|
|
||||||
private readonly Lazy<string> _lazyDiscriminator = new Lazy<string>(GetAppDiscriminatorCore);
|
|
||||||
|
|
||||||
public string Discriminator => _lazyDiscriminator.Value;
|
|
||||||
|
|
||||||
private static string GetAppDiscriminatorCore()
|
|
||||||
{
|
|
||||||
return HttpRuntime.AppDomainAppId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Entry point for the application.
|
// Entry point for the application.
|
||||||
public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run<Startup>(args);
|
public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run<Startup>(args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
|
||||||
|
|
||||||
namespace Yavsc
|
namespace Yavsc
|
||||||
{
|
{
|
||||||
public class AuthorisationView {
|
public class AuthorisationView {
|
||||||
public OpenIdConnectMessage Message { get; set; }
|
|
||||||
public Application Application { get; set; }
|
public Application Application { get; set; }
|
||||||
|
public IEnumerable<string> Scopes { get; set; }
|
||||||
|
public string RedirectUrl { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
@using System.Collections.Generic
|
|
||||||
@using Microsoft.AspNet.Http
|
|
||||||
@using Microsoft.AspNet.Http.Authentication
|
|
||||||
@model LoginViewModel
|
|
||||||
@inject SignInManager<ApplicationUser> SignInManager
|
|
||||||
|
|
||||||
|
@using Microsoft.AspNet.Http.Authentication
|
||||||
|
@using Yavsc.ViewModels.Account
|
||||||
|
@model LoginViewModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = SR["Log in"];
|
ViewData["Title"] = SR["Log in"];
|
||||||
}
|
}
|
||||||
|
|
||||||
<h2>@ViewData["Title"]</h2>
|
<div class="jumbotron">
|
||||||
<div class="row">
|
<h1>@ViewData["Title"]</h1>
|
||||||
<div class="col-md-8">
|
<hr/>
|
||||||
<section>
|
|
||||||
<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
|
<h2 class="lead text-left">@SR["Use a local account to log in"]</h2>
|
||||||
<h4>@SR["Use a local account to log in."]</h4>
|
<form action="@Constants.LoginPath" method="post" class="form-horizontal" role="form">
|
||||||
<hr />
|
|
||||||
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>
|
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="UserName" class="col-md-2 control-label">@SR["UserName"]</label>
|
<label for="UserName" class="col-md-2 control-label">@SR["UserName"]</label>
|
||||||
|
|
@ -40,25 +38,24 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-offset-2 col-md-10">
|
<div class="col-md-offset-2 col-md-10">
|
||||||
<button type="submit" class="btn btn-default">@SR["Login"]</button>
|
<button type="submit" class="btn btn-lg btn-success">@SR["Login"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<a asp-action="Register">@SR["Register as a new user?"]</a>
|
<a asp-action="Register" asp-controller="Account">@SR["Register as a new user"]?</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a asp-action="ForgotPassword">@SR["Forgot your password?"]</a>
|
<a asp-action="ForgotPassword" asp-controller="Account">@SR["Forgot your password"]?</a>
|
||||||
</p>
|
</p>
|
||||||
|
<input type="hidden" name="Provider" value="LOCAL" />
|
||||||
|
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||||
|
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
</form>
|
</form>
|
||||||
</section>
|
|
||||||
</div>
|
<hr/>
|
||||||
<div class="col-md-4">
|
<h2 class="lead text-left">@SR["Use another service to log in"]:</h2>
|
||||||
<section>
|
@if (Model.ExternalProviders?.Count() == 0)
|
||||||
<h4>@SR["Use another service to log in."]</h4>
|
|
||||||
<hr />
|
|
||||||
@{
|
|
||||||
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
|
|
||||||
if (loginProviders.Count == 0)
|
|
||||||
{
|
{
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -69,22 +66,13 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
|
@foreach (var description in Model.ExternalProviders) {
|
||||||
<div>
|
<form action="@Constants.LoginPath" method="post">
|
||||||
<p>
|
<input type="hidden" name="Provider" value="@description.AuthenticationScheme" />
|
||||||
@foreach (var provider in loginProviders)
|
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||||
{
|
<button class="btn btn-lg btn-success" type="submit">@SR["Connect using"] @description.DisplayName</button>
|
||||||
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
|
@Html.AntiForgeryToken()
|
||||||
}
|
</form>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section Scripts {
|
|
||||||
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
|
|
||||||
}
|
|
||||||
|
|
|
||||||
32
Yavsc/Views/OAuth/Authorize.cshtml
Normal file
32
Yavsc/Views/OAuth/Authorize.cshtml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
@using Microsoft.AspNet.Http.Authentication
|
||||||
|
@using Microsoft.AspNet.WebUtilities
|
||||||
|
@using System.Security.Claims
|
||||||
|
@{
|
||||||
|
AuthenticationManager authentication = Context.Authentication;
|
||||||
|
ClaimsPrincipal principal = authentication.AuthenticateAsync(Constants.ApplicationAuthenticationSheme).Result;
|
||||||
|
string[] scopes = QueryHelpers.ParseQuery(Context.Request.QueryString.Value)["scope"];
|
||||||
|
}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Authorize</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Authorization Server</h1>
|
||||||
|
<h2>OAuth2 Authorize</h2>
|
||||||
|
<form method="POST">
|
||||||
|
<p>Hello, @principal.Identity.Name</p>
|
||||||
|
<p>A third party application want to do the following on your behalf:</p>
|
||||||
|
<ul>
|
||||||
|
@foreach (var scope in scopes)
|
||||||
|
{
|
||||||
|
<li>@scope</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<input type="submit" name="submit.Grant" value="Grant" />
|
||||||
|
<input type="submit" name="submit.Login" value="Sign in as different user" />
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
Yavsc/Views/OAuth/AuthorizeError.cshtml
Normal file
20
Yavsc/Views/OAuth/AuthorizeError.cshtml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
@using Microsoft.AspNet.Http
|
||||||
|
@using System
|
||||||
|
@using System.Security.Claims
|
||||||
|
@{
|
||||||
|
var error = Context.Items["oauth.Error"];
|
||||||
|
var errorDescription = Context.Items["oauth.ErrorDescription"];
|
||||||
|
var errorUri = Context.Items["oauth.ErrorUri"];
|
||||||
|
}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Authorize Error</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Katana.Sandbox.WebServer</h1>
|
||||||
|
<h2>OAuth2 Authorize Error</h2>
|
||||||
|
<p>Error: @error</p>
|
||||||
|
<p>@errorDescription</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
@using AspNet.Security.OpenIdConnect.Extensions
|
|
||||||
@using Microsoft.IdentityModel.Protocols.OpenIdConnect
|
|
||||||
|
|
||||||
|
|
||||||
@model AuthorisationView
|
@model AuthorisationView
|
||||||
|
|
||||||
<div class="jumbotron">
|
<div class="jumbotron">
|
||||||
<h1>Authorization</h1>
|
<h1>Authorization @Application?.DisplayName</h1>
|
||||||
|
|
||||||
|
<p>@Model.Message</p>
|
||||||
|
|
||||||
<p class="lead text-left">Do you wanna grant <strong>@Model.Application.DisplayName</strong> an access to your resources? (scopes requested: @Model.Message.Scope)</p>
|
<p class="lead text-left">Do you wanna grant <strong>@Model.Application.DisplayName</strong> an access to your resources? (scopes requested: @Model.Message.Scope)</p>
|
||||||
|
|
||||||
<form enctype="application/x-www-form-urlencoded" method="post">
|
<form enctype="application/x-www-form-urlencoded" method="post">
|
||||||
@Html.AntiForgeryToken()
|
@Html.AntiForgeryToken()
|
||||||
|
|
||||||
@foreach (var parameter in Model.Message.Parameters) {
|
@foreach (var scope in Model.Scopes) {
|
||||||
<input type="hidden" name="@parameter.Key" value="@parameter.Value" />
|
<li>@scope</li>
|
||||||
}
|
}
|
||||||
<input formaction="/connect/authorize/accept" class="btn btn-lg btn-success" name="Authorize" type="submit" value="Yeah, sure" />
|
@Html.Hidden("ReturnUrl")
|
||||||
<input formaction="/api/token/get" class="btn btn-lg btn-success" name="Authorize" type="submit" value="hum" />
|
<input formaction="/oauth/accept" class="btn btn-lg btn-success" name="Authorize" type="submit" value="Yeah, sure" />
|
||||||
<input formaction="/connect/authorize/deny" class="btn btn-lg btn-danger" name="Deny" type="submit" value="Hell, no" />
|
<input formaction="/oauth/deny" class="btn btn-lg btn-danger" name="Deny" type="submit" value="Hell, no" />
|
||||||
</form>
|
<input formaction="/oauth/deny" class="btn btn-lg btn-success" name="Submit.Login" type="submit" value="Login using another account" />
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
<h2 class="lead text-left">@SR["Use a local account to log in"]</h2>
|
<h2 class="lead text-left">@SR["Use a local account to log in"]</h2>
|
||||||
<form action="/login" method="post" class="form-horizontal" role="form">
|
<form action="@Constants.LoginPath" method="post" class="form-horizontal" role="form">
|
||||||
|
|
||||||
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>
|
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@foreach (var description in Model.ExternalProviders) {
|
@foreach (var description in Model.ExternalProviders) {
|
||||||
<form action="/signin" method="post">
|
<form action="@Constants.LoginPath" method="post">
|
||||||
<input type="hidden" name="Provider" value="@description.AuthenticationScheme" />
|
<input type="hidden" name="Provider" value="@description.AuthenticationScheme" />
|
||||||
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||||
<button class="btn btn-lg btn-success" type="submit">@SR["Connect using"] @description.DisplayName</button>
|
<button class="btn btn-lg btn-success" type="submit">@SR["Connect using"] @description.DisplayName</button>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ gulp.task("min:css", function () {
|
||||||
|
|
||||||
gulp.task("min", ["min:js", "min:css"]);
|
gulp.task("min", ["min:js", "min:css"]);
|
||||||
|
|
||||||
gulp.task('watch', shell.task(['MONO_OPTIONS=--debug ASPNET_ENV=Development dnx-watch web --configuration=Debug']))
|
gulp.task('watch', shell.task(['ASPNET_ENV=Development dnx-watch web --configuration=Debug']))
|
||||||
|
|
||||||
gulp.task('build', shell.task(['dnu build --configuration=Debug']))
|
gulp.task('build', shell.task(['dnu build --configuration=Debug']))
|
||||||
gulp.task('publish', shell.task(['dnu publish -o ../build']))
|
gulp.task('publish', shell.task(['dnu publish -o ../build']))
|
||||||
|
|
|
||||||
|
|
@ -88,18 +88,15 @@
|
||||||
"Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final",
|
"Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final",
|
||||||
"Microsoft.Extensions.Localization": "1.0.0-rc1-final",
|
"Microsoft.Extensions.Localization": "1.0.0-rc1-final",
|
||||||
"Microsoft.Extensions.Localization.Abstractions": "1.0.0-rc1-final",
|
"Microsoft.Extensions.Localization.Abstractions": "1.0.0-rc1-final",
|
||||||
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
|
|
||||||
"Microsoft.Framework.DependencyInjection": "1.0.0-beta8",
|
|
||||||
|
|
||||||
"Microsoft.Extensions.CodeGeneration": "1.0.0-rc1-final",
|
"Microsoft.Extensions.CodeGeneration": "1.0.0-rc1-final",
|
||||||
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc1-final",
|
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc1-final",
|
||||||
"Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
|
"Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
|
||||||
|
"Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8",
|
||||||
|
"Microsoft.Framework.Configuration.Binder": "1.0.0-beta8",
|
||||||
|
"Microsoft.Framework.Configuration.Json": "1.0.0-beta8",
|
||||||
"Microsoft.AspNet.Session": "1.0.0-rc1-final",
|
"Microsoft.AspNet.Session": "1.0.0-rc1-final",
|
||||||
"Microsoft.NETCore.Platforms": "1.0.1-beta-23516",
|
"Microsoft.NETCore.Platforms": "1.0.1-beta-23516",
|
||||||
"Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8",
|
|
||||||
"Microsoft.Framework.Configuration.Json": "1.0.0-beta8",
|
|
||||||
"Microsoft.Framework.DependencyInjection.Abstractions": "1.0.0-beta8",
|
|
||||||
"Microsoft.Framework.Configuration.Binder": "1.0.0-beta8",
|
|
||||||
"Microsoft.AspNet.Web.Optimization": "1.1.3",
|
"Microsoft.AspNet.Web.Optimization": "1.1.3",
|
||||||
"Microsoft.Extensions.WebEncoders.Core": "1.0.0-rc1-final",
|
"Microsoft.Extensions.WebEncoders.Core": "1.0.0-rc1-final",
|
||||||
"Microsoft.AspNetCore.Authentication.OAuth": "0.0.1-alpha",
|
"Microsoft.AspNetCore.Authentication.OAuth": "0.0.1-alpha",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
2
external/oauth-aspnet
vendored
2
external/oauth-aspnet
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3ce8e249032e49263b4d4e4c9009fd13a39f6415
|
Subproject commit 1fdf3cb799188891aa0fcb924cb7888d6d1bd92d
|
||||||
|
|
@ -67,7 +67,7 @@ namespace testOauthClient
|
||||||
app.UseOAuthAuthentication(
|
app.UseOAuthAuthentication(
|
||||||
options => {
|
options => {
|
||||||
options.AuthenticationScheme="yavsc";
|
options.AuthenticationScheme="yavsc";
|
||||||
options.AuthorizationEndpoint="http://dev.pschneider.fr/signin";
|
options.AuthorizationEndpoint="http://dev.pschneider.fr/authorize";
|
||||||
options.TokenEndpoint="http://dev.pschneider.fr/token";
|
options.TokenEndpoint="http://dev.pschneider.fr/token";
|
||||||
options.AutomaticAuthenticate=true;
|
options.AutomaticAuthenticate=true;
|
||||||
options.AutomaticChallenge=true;
|
options.AutomaticChallenge=true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue