fixe du style, des trads, et touche le WF
This commit is contained in:
@ -152,6 +152,7 @@
|
||||
<data name="Change"><value>Changer</value></data>
|
||||
<data name="Change user name form"><value>Formulaire de changement de pseudonyme (avatar, le nom publique de ce compte utilisateur ici)</value></data>
|
||||
<data name="Change your account settings"><value>Modifiez les paramètres de votre compte</value></data>
|
||||
<data name="Connect using"><value>Se connecter en utilisant</value></data>
|
||||
<data name="ChooseADescription"><value>S'il vous plait, choisissez une description.</value></data>
|
||||
<data name="ChooseATitle"><value>S'il vous plait, choisissez un titre.</value></data>
|
||||
<data name="ChooseADateInTheFutur"><value>S'il vous plait, choisissez une date dans le futur.</value></data>
|
||||
@ -201,7 +202,7 @@
|
||||
<data name="Fill in your book query"><value>Saisissez votre demande de rendez-vous</value></data>
|
||||
<data name="Forbidden"><value>Contenu à accès restreint</value></data>
|
||||
|
||||
<data name="Forgot your password?"><value>Mot de passe oublié?</value></data>
|
||||
<data name="Forgot your password"><value>Mot de passe oublié</value></data>
|
||||
<data name="from"><value>provenant de</value></data>
|
||||
<data name="GoogleDidntGeoLocalized"><value>Google n'a pas pu identifier ce lieu</value></data>
|
||||
<data name="Google calendar"><value>Agenda Google</value></data>
|
||||
@ -280,7 +281,7 @@
|
||||
<data name="ReadMore"><value>Lire la suite ...</value></data>
|
||||
<data name="reason"><value>raison</value></data>
|
||||
<data name="Register"><value>S'inscrire</value></data>
|
||||
<data name="Register as a new user?"><value>S'inscrire comme nouvel utilisateur?</value></data>
|
||||
<data name="Register as a new user"><value>S'inscrire comme nouvel utilisateur</value></data>
|
||||
<data name="RegistrationUnexpectedError"><value>Une erreur inattendue s'est produite:
|
||||
"{0}".
|
||||
Veuillez pardonner la gêne occasionnée</value></data>
|
||||
@ -321,8 +322,8 @@
|
||||
<data name="TwoFactorAuthentication"><value>Double identification</value></data>
|
||||
<data name="Unitary_cost"><value>Coût unitaire</value></data>
|
||||
<data name="Unregister"><value>Se désinscrire</value></data>
|
||||
<data name="Use a local account to log in."><value>Utiliser un compte local pour se connecter.</value></data>
|
||||
<data name="Use another service to log in."><value>Utiliser un autre service pour se connecter.</value></data>
|
||||
<data name="Use a local account to log in"><value>Utiliser un compte local pour se connecter</value></data>
|
||||
<data name="Use another service to log in"><value>Utiliser un autre service pour se connecter</value></data>
|
||||
<data name="User List"><value>Liste des utilisateurs</value><comment></comment></data>
|
||||
<data name="UserName"><value>Nom d'utilisateur</value></data>
|
||||
<data name="UsersInRole"><value>Liste des utilisateurs assumant le rôle "{0}"</value></data>
|
||||
|
@ -8,7 +8,7 @@
|
||||
ViewData["Title"] = SR["Log in"];
|
||||
}
|
||||
|
||||
<h2>@ViewData["Title"].</h2>
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<section>
|
||||
|
@ -93,3 +93,7 @@ L'opération est annulable, jusqu'à deux semaines après sa programmation.
|
||||
|
||||
|
||||
|
||||
@foreach (var claim in Context.User.Claims) {
|
||||
<div>@claim.Type: <b>@claim.Value</b></div>
|
||||
}
|
||||
|
@ -2,23 +2,26 @@
|
||||
@using Microsoft.AspNet.Http.Authentication
|
||||
@using Yavsc.ViewModels.Account
|
||||
@model LoginViewModel
|
||||
@{
|
||||
ViewData["Title"] = SR["Log in"];
|
||||
}
|
||||
|
||||
<div class="jumbotron">
|
||||
<h1>Authentication</h1>
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<hr/>
|
||||
<h2 class="lead text-left">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">
|
||||
|
||||
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label for="UserName" class="col-md-2 control-label">User name</label>
|
||||
<label for="UserName" class="col-md-2 control-label">@SR["UserName"]</label>
|
||||
<div class="col-md-10">
|
||||
<input asp-for="UserName" class="form-control" />
|
||||
<span asp-validation-for="UserName" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="col-md-2 control-label">Password</label>
|
||||
<label for="Password" class="col-md-2 control-label">@SR["Password"]</label>
|
||||
<div class="col-md-10">
|
||||
<input asp-for="Password" class="form-control" />
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
@ -26,28 +29,47 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button type="submit" class="btn btn-lg btn-success">Login</button>
|
||||
<div class="checkbox">
|
||||
<input asp-for="RememberMe" />
|
||||
<label for="RememberMe" class="control-label">@SR["Remember me"]</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<button type="submit" class="btn btn-lg btn-success">@SR["Login"]</button>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<a asp-action="Register">Register as a new user?</a>
|
||||
<a asp-action="Register" asp-controller="Account">@SR["Register as a new user"]?</a>
|
||||
</p>
|
||||
<p>
|
||||
<a asp-action="ForgotPassword">Forgot your password?</a>
|
||||
<a asp-action="ForgotPassword" asp-controller="Account">@SR["Forgot your password"]?</a>
|
||||
</p>
|
||||
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
<h2 class="lead text-left">Sign in using one of these external providers:</h2>
|
||||
@foreach (var description in Model.ExternalProviders) {
|
||||
<h2 class="lead text-left">@SR["Use another service to log in"]:</h2>
|
||||
@if (Model.ExternalProviders.Count() == 0)
|
||||
{
|
||||
<div>
|
||||
<p>
|
||||
There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
|
||||
for details on setting up this ASP.NET application to support logging in via external services.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var description in Model.ExternalProviders) {
|
||||
<form action="/signin" method="post">
|
||||
<input type="hidden" name="Provider" value="@description.AuthenticationScheme" />
|
||||
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||
<button class="btn btn-lg btn-success" type="submit">Connect using @description.DisplayName</button>
|
||||
<button class="btn btn-lg btn-success" type="submit">@SR["Connect using"] @description.DisplayName</button>
|
||||
@Html.AntiForgeryToken()
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</div>
|
@ -9,7 +9,7 @@
|
||||
<a asp-controller="Manage" class="navbar-link" asp-action="Index" title="Manage">@SR["Hello"] @User.GetUserName()!</a>
|
||||
</li>
|
||||
<li>
|
||||
<button type="submit" class="navbar-link">@SR["Logout"]</button>
|
||||
<button type="submit" class="btn btn-link">@SR["Logout"]</button>
|
||||
</li>
|
||||
</ul>
|
||||
</language-layout>
|
||||
@ -19,7 +19,7 @@ else
|
||||
{ <language-layout>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a class="navbar-link" asp-controller="Account" asp-action="Register">@SR["Register"]</a></li>
|
||||
<li><a class="navbar-link" asp-controller="Account" asp-action="SignIn">@SR["Login"]</a></li>
|
||||
<li><a class="navbar-link" asp-controller="OAuth" asp-action="SignIn">@SR["Login"]</a></li>
|
||||
</ul>
|
||||
</language-layout>
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
@ -51,71 +50,13 @@ namespace Yavsc.Controllers
|
||||
_twilioSettings = twilioSettings.Value;
|
||||
_logger = loggerFactory.CreateLogger<AccountController>();
|
||||
}
|
||||
[HttpGet("~/signin")]
|
||||
public ActionResult SignIn(string returnUrl = "/")
|
||||
{
|
||||
return View("SignIn", new LoginViewModel
|
||||
{
|
||||
ReturnUrl = returnUrl,
|
||||
ExternalProviders = _signInManager.GetExternalAuthenticationSchemes()
|
||||
});
|
||||
/* When using an external login provider :
|
||||
// Request a redirect to the external login provider.
|
||||
var redirectUrl = returnUrl ?? "/";
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(OpenIdConnectDefaults.AuthenticationScheme, redirectUrl);
|
||||
return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, properties);
|
||||
*/
|
||||
}
|
||||
|
||||
[HttpGet("~/signout"), HttpPost("~/signout")]
|
||||
public async Task<IActionResult> SignOut(string returnUrl = "/")
|
||||
{
|
||||
// Instruct the cookies middleware to delete the local cookie created when the user agent
|
||||
// is redirected from the identity provider after a successful authorization flow and
|
||||
// to redirect the user agent to the identity provider to sign out.
|
||||
await _signInManager.SignOutAsync();
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
|
||||
|
||||
public IActionResult Forbidden()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost("~/signin")]
|
||||
public async Task<IActionResult> SignIn(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("null provider");
|
||||
ModelState.AddModelError("provider", "provider cannot be null");
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
|
||||
// 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($"null returnUrl ({provider}) ");
|
||||
ModelState.AddModelError("returnUrl", "returnUrl cannot be null");
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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);
|
||||
}
|
||||
|
||||
[HttpPost("~/login")]
|
||||
public async Task<IActionResult> LocalLogin(LoginViewModel model)
|
||||
{
|
||||
@ -195,7 +136,7 @@ namespace Yavsc.Controllers
|
||||
_logger.LogInformation(4, "User logged out.");
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// POST: /Account/ExternalLogin
|
||||
[HttpPost]
|
||||
@ -216,7 +157,7 @@ namespace Yavsc.Controllers
|
||||
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||||
if (info == null)
|
||||
{
|
||||
return RedirectToAction(nameof(SignIn));
|
||||
return Redirect("~/signin"); // RedirectToAction(nameof(OAuthController.SignIn));
|
||||
}
|
||||
|
||||
// Sign in the user with this external login provider if the user already has a login.
|
||||
|
359
Yavsc/src/Controllers/OAuthController.cs
Normal file
359
Yavsc/src/Controllers/OAuthController.cs
Normal file
@ -0,0 +1,359 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AspNet.Security.OpenIdConnect.Extensions;
|
||||
using AspNet.Security.OpenIdConnect.Server;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.DataProtection.KeyManagement;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Yavsc.Extensions;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.ViewModels.Account;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class OAuthController : Controller
|
||||
{
|
||||
ApplicationDbContext _context;
|
||||
UserManager<ApplicationUser> _userManager;
|
||||
|
||||
ILogger _logger;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private TokenAuthOptions _tokenOptions;
|
||||
|
||||
public OAuthController(ApplicationDbContext context, SignInManager<ApplicationUser> signInManager, IKeyManager keyManager,
|
||||
IOptions<TokenAuthOptions> tokenOptions,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILoggerFactory loggerFactory
|
||||
)
|
||||
{
|
||||
_context = context;
|
||||
_signInManager = signInManager;
|
||||
_tokenOptions = tokenOptions.Value;
|
||||
_userManager = userManager;
|
||||
_logger = loggerFactory.CreateLogger<OAuthController>();
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/signin")]
|
||||
public ActionResult SignIn(string returnUrl = "/Account/ExternalLoginCallback") {
|
||||
// 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.
|
||||
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);
|
||||
*/
|
||||
}
|
||||
|
||||
[HttpPost("~/signin")]
|
||||
public IActionResult SignIn( 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();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, ReturnUrl);
|
||||
return new ChallengeResult(Provider, properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("~/signout"), HttpPost("~/signout")]
|
||||
public async Task SignOut() {
|
||||
// Instruct the cookies middleware to delete the local cookie created
|
||||
// when the user agent is redirected from the external identity provider
|
||||
// after a successful authentication flow (e.g Google or Facebook).
|
||||
|
||||
await HttpContext.Authentication.SignOutAsync("ServerCookie");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpGet("~/api/getclaims"), Produces("application/json")]
|
||||
|
||||
public IActionResult GetClaims()
|
||||
{
|
||||
var identity = User.Identity as ClaimsIdentity;
|
||||
|
||||
var claims = from c in identity.Claims
|
||||
select new
|
||||
{
|
||||
subject = c.Subject.Name,
|
||||
type = c.Type,
|
||||
value = c.Value
|
||||
};
|
||||
|
||||
return Ok(claims);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/connect/authorize"), HttpPost("~/connect/authorize")]
|
||||
public async Task<IActionResult> Authorize(CancellationToken cancellationToken) {
|
||||
// Note: when a fatal error occurs during the request processing, an OpenID Connect response
|
||||
// is prematurely forged and added to the ASP.NET context by OpenIdConnectServerHandler.
|
||||
// You can safely remove this part and let ASOS automatically handle the unrecoverable errors
|
||||
// by switching ApplicationCanDisplayErrors to false in Startup.cs.
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response == null) {
|
||||
_logger.LogError("GetOpenIdConnectResponse is null");
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
// Extract the authorization request from the ASP.NET environment.
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
_logger.LogError("An internal error has occurred, GetOpenIdConnectRequest is null");
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
// Note: authentication could be theorically enforced at the filter level via AuthorizeAttribute
|
||||
// but this authorization endpoint accepts both GET and POST requests while the cookie middleware
|
||||
// only uses 302 responses to redirect the user agent to the login page, making it incompatible with POST.
|
||||
// To work around this limitation, the OpenID Connect request is automatically saved in the cache and will be
|
||||
// restored by the OpenID Connect server middleware after the external authentication process has been completed.
|
||||
|
||||
if (!User.Identities.Any(identity => identity.IsAuthenticated)) {
|
||||
_logger.LogWarning("new ChallengeResult");
|
||||
return new ChallengeResult(new AuthenticationProperties {
|
||||
RedirectUri = Url.Action(nameof(Authorize), new {
|
||||
request_id = request.GetUniqueIdentifier()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Note: ASOS automatically ensures that an application corresponds to the client_id specified
|
||||
// in the authorization request by calling IOpenIdConnectServerProvider.ValidateAuthorizationRequest.
|
||||
// In theory, this null check shouldn't be needed, but a race condition could occur if you
|
||||
// manually removed the application details from the database after the initial check made by ASOS.
|
||||
var application = await GetApplicationAsync(request.ClientId, cancellationToken);
|
||||
if (application == null) {
|
||||
_logger.LogError("Details concerning the calling client application cannot be found in the database");
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.InvalidClient,
|
||||
ErrorDescription = "Details concerning the calling client application cannot be found in the database"
|
||||
});
|
||||
}
|
||||
|
||||
// Note: in a real world application, you'd probably prefer creating a specific view model.
|
||||
return View("Authorize", Tuple.Create(request, application));
|
||||
}
|
||||
|
||||
[Authorize, HttpPost("~/connect/authorize/accept"), ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Accept(CancellationToken cancellationToken) {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new ClaimsIdentity containing the claims that
|
||||
// will be used to create an id_token, a token or a code.
|
||||
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
|
||||
// Copy the claims retrieved from the external identity provider
|
||||
// (e.g Google, Facebook, a WS-Fed provider or another OIDC server).
|
||||
foreach (var claim in HttpContext.User.Claims) {
|
||||
// Allow ClaimTypes.Name to be added in the id_token.
|
||||
// ClaimTypes.NameIdentifier is automatically added, even if its
|
||||
// destination is not defined or doesn't include "id_token".
|
||||
// The other claims won't be visible for the client application.
|
||||
/*
|
||||
if (claim.Type == ClaimTypes.Name) {
|
||||
claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken,
|
||||
OpenIdConnectConstants.Destinations.IdentityToken);
|
||||
}
|
||||
*/
|
||||
if (claim.Type == ClaimTypes.Name) {
|
||||
claim.WithDestination("code");
|
||||
claim.WithDestination("id_token");
|
||||
}
|
||||
identity.AddClaim(claim);
|
||||
}
|
||||
|
||||
var application = await GetApplicationAsync(request.ClientId, cancellationToken);
|
||||
if (application == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.InvalidClient,
|
||||
ErrorDescription = "Details concerning the calling client application cannot be found in the database"
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new ClaimsIdentity containing the claims associated with the application.
|
||||
// Note: setting identity.Actor is not mandatory but can be useful to access
|
||||
// the whole delegation chain from the resource server (see ResourceController.cs).
|
||||
identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID);
|
||||
identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName,"code id_token");
|
||||
|
||||
var properties = new AuthenticationProperties();
|
||||
|
||||
// Note: you can change the list of scopes granted
|
||||
// to the client application using SetScopes:
|
||||
properties.SetScopes(new[] {
|
||||
/* openid: */ OpenIdConnectConstants.Scopes.OpenId,
|
||||
/* email: */ OpenIdConnectConstants.Scopes.Email,
|
||||
/* profile: */ OpenIdConnectConstants.Scopes.Profile,
|
||||
/* api-resource-controller: */ "api-resource-controller"
|
||||
});
|
||||
|
||||
// You can also limit the resources endpoints
|
||||
// the access token should be issued for:
|
||||
properties.SetResources(new[] {
|
||||
"http://localhost:54540/"
|
||||
});
|
||||
|
||||
// This call will instruct AspNet.Security.OpenIdConnect.Server to serialize
|
||||
// the specified identity to build appropriate tokens (id_token and token).
|
||||
// Note: you should always make sure the identities you return contain either
|
||||
// a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned
|
||||
// identities always contain the name identifier returned by the external provider.
|
||||
// Note: the authenticationScheme parameter must match the value configured in Startup.cs.
|
||||
await HttpContext.Authentication.SignInAsync(
|
||||
OpenIdConnectServerDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(identity), properties);
|
||||
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
[Authorize, HttpPost("~/connect/authorize/deny"), ValidateAntiForgeryToken]
|
||||
public IActionResult Deny(CancellationToken cancellationToken) {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Notify AspNet.Security.OpenIdConnect.Server that the authorization grant has been denied.
|
||||
// Note: OpenIdConnectServerHandler will automatically take care of redirecting
|
||||
// the user agent to the client application using the appropriate response_mode.
|
||||
HttpContext.SetOpenIdConnectResponse(new OpenIdConnectMessage {
|
||||
Error = "access_denied",
|
||||
ErrorDescription = "The authorization grant has been denied by the resource owner",
|
||||
RedirectUri = request.RedirectUri,
|
||||
State = request.State
|
||||
});
|
||||
|
||||
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
[HttpGet("~/connect/logout")]
|
||||
public async Task<ActionResult> Logout() {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
_logger.LogError("GetOpenIdConnectResponse is null");
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
// When invoked, the logout endpoint might receive an unauthenticated request if the server cookie has expired.
|
||||
// When the client application sends an id_token_hint parameter, the corresponding identity can be retrieved
|
||||
// using AuthenticateAsync or using User when the authorization server is declared as AuthenticationMode.Active.
|
||||
var identity = await HttpContext.Authentication.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
_logger.LogError("An internal error has occurred");
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
return View("Logout", Tuple.Create(request, identity));
|
||||
}
|
||||
|
||||
[HttpPost("~/connect/logout")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task Logout(CancellationToken cancellationToken) {
|
||||
// Instruct the cookies middleware to delete the local cookie created
|
||||
// when the user agent is redirected from the external identity provider
|
||||
// after a successful authentication flow (e.g Google or Facebook).
|
||||
await HttpContext.Authentication.SignOutAsync("ServerCookie");
|
||||
|
||||
// This call will instruct AspNet.Security.OpenIdConnect.Server to serialize
|
||||
// the specified identity to build appropriate tokens (id_token and token).
|
||||
// Note: you should always make sure the identities you return contain either
|
||||
// a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned
|
||||
// identities always contain the name identifier returned by the external provider.
|
||||
await HttpContext.Authentication.SignOutAsync(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
}
|
||||
|
||||
protected virtual Task<Application> GetApplicationAsync(string identifier, CancellationToken cancellationToken)
|
||||
{
|
||||
// Retrieve the application details corresponding to the requested client_id.
|
||||
return (from application in _context.Applications
|
||||
where application.ApplicationID == identifier
|
||||
select application).SingleOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
private async Task<ApplicationUser> GetCurrentUserAsync()
|
||||
{
|
||||
return await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
|
||||
}
|
||||
|
||||
private IActionResult RedirectToLocal(string returnUrl)
|
||||
{
|
||||
if (Url.IsLocalUrl(returnUrl))
|
||||
{
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,12 @@ public partial class Service : BaseProduct
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public decimal? Pricing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Associate a class of flow worker to handle with
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Specification { get; set; }
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
public class WorkflowReference {
|
||||
/// <summary>
|
||||
/// Friendly name for this kind of service
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Service code found in the catalog
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Key]
|
||||
string SpecificationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Moderation settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string ModeratorGroupName { get; set; }
|
||||
}
|
||||
|
||||
public class SiteSettings
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Slogan { get; set; }
|
||||
/// <summary>
|
||||
/// Conceptually,
|
||||
/// This authorisation server only has this present site as unique audience.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Audience { get; set; }
|
||||
/// <summary>
|
||||
/// it's a very small company, with one domaine name only,
|
||||
/// so let it be the same as in the Audience field.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Authority { get; set; }
|
||||
public EmailEntry Owner { get; set; }
|
||||
public EmailEntry Admin { get; set; }
|
||||
public ThirdPartyFiles UserFiles { get; set; }
|
||||
/// <summary>
|
||||
/// Configured services
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<WorkflowReference> WorkFlow { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ using System.Web.Optimization;
|
||||
using AspNet.Security.OpenIdConnect.Extensions;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.Cookies;
|
||||
using Microsoft.AspNet.Authentication.JwtBearer;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Builder;
|
||||
@ -159,16 +158,6 @@ namespace Yavsc
|
||||
{
|
||||
options.SignInScheme = "ServerCookie";
|
||||
});
|
||||
services.Configure<TokenAuthOptions>(
|
||||
to =>
|
||||
{
|
||||
to.Audience = Configuration["Site:Audience"];
|
||||
to.Issuer = Configuration["Site:Authority"];
|
||||
to.SigningCredentials =
|
||||
new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SiteSettings>), typeof(OptionsManager<SiteSettings>)));
|
||||
services.Add(ServiceDescriptor.Singleton(typeof(IOptions<SmtpSettings>), typeof(OptionsManager<SmtpSettings>)));
|
||||
@ -188,9 +177,11 @@ namespace Yavsc
|
||||
configure.PersistKeysToFileSystem(
|
||||
new DirectoryInfo(Configuration["DataProtection:Keys:Dir"]));
|
||||
});
|
||||
|
||||
services.AddAuthentication(options => {
|
||||
options.SignInScheme = "ServerCookie"; }
|
||||
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.SignInScheme = "ServerCookie";
|
||||
}
|
||||
);
|
||||
// Add framework services.
|
||||
services.AddEntityFramework()
|
||||
@ -233,11 +224,14 @@ namespace Yavsc
|
||||
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.AddPolicy("AdministratorOnly", policy => policy.RequireRole(Constants.AdminGroupName));
|
||||
options.AddPolicy("AdministratorOnly", policy =>
|
||||
{
|
||||
policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName);
|
||||
});
|
||||
|
||||
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
|
||||
options.AddPolicy("API", policy =>
|
||||
{
|
||||
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
|
||||
policy.RequireClaim(OpenIdConnectConstants.Claims.Scope, "api-resource-controller");
|
||||
});
|
||||
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
||||
@ -344,6 +338,10 @@ namespace Yavsc
|
||||
}
|
||||
}
|
||||
|
||||
var udirinfo = new DirectoryInfo(Configuration["Site:UserFiles:RootDir"]);
|
||||
if (!udirinfo.Exists)
|
||||
throw new Exception($"Configuration value for Site:UserFiles:RootDir : {udirinfo.FullName}");
|
||||
|
||||
|
||||
var googleOptions = new GoogleOptions
|
||||
{
|
||||
@ -426,16 +424,16 @@ namespace Yavsc
|
||||
{
|
||||
options.Provider = new AuthorizationProvider(loggerFactory);
|
||||
|
||||
// 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"); */
|
||||
// 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.SigningCredentials.AddKey(key);
|
||||
// Note: see AuthorizationController.cs for more
|
||||
// information concerning ApplicationCanDisplayErrors.
|
||||
options.ApplicationCanDisplayErrors = true;
|
||||
options.AllowInsecureHttp = true;
|
||||
options.AutomaticChallenge = true;
|
||||
options.AuthorizationEndpointPath = new PathString("/connect/authorize");
|
||||
@ -443,21 +441,16 @@ namespace Yavsc
|
||||
options.UseSlidingExpiration = true;
|
||||
options.AllowInsecureHttp = true;
|
||||
options.AuthenticationScheme = "oidc"; // was = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
options.LogoutEndpointPath = new PathString("/connect/logout");
|
||||
/* options.ValidationEndpointPath = new PathString("/connect/introspect"); */
|
||||
options.LogoutEndpointPath = new PathString("/connect/logout");
|
||||
/* options.ValidationEndpointPath = new PathString("/connect/introspect"); */
|
||||
});
|
||||
|
||||
|
||||
var udirinfo = new DirectoryInfo(Configuration["Site:UserFiles:RootDir"]);
|
||||
if (!udirinfo.Exists)
|
||||
throw new Exception($"Configuration value for Site:UserFiles:RootDir : {udirinfo.FullName}");
|
||||
|
||||
app.UseFileServer(new FileServerOptions()
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
udirinfo.FullName),
|
||||
RequestPath = new PathString(Constants.UserFilesRequestPath),
|
||||
EnableDirectoryBrowsing = true
|
||||
EnableDirectoryBrowsing = false
|
||||
});
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user