oidc reloaded
This commit is contained in:
@ -9,6 +9,7 @@
|
||||
<div class="jumbotron">
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<hr/>
|
||||
|
||||
<h2 class="lead text-left">@SR["Use a local account to log in"]</h2>
|
||||
<form action="/login" method="post" class="form-horizontal" role="form">
|
||||
|
||||
@ -46,8 +47,8 @@
|
||||
<p>
|
||||
<a asp-action="ForgotPassword" asp-controller="Account">@SR["Forgot your password"]?</a>
|
||||
</p>
|
||||
|
||||
<input type="hidden" name="ReturnUrl" value="@Model.AfterLoginRedirectUrl" />
|
||||
<input type="hidden" name="Provider" value="LOCAL" />
|
||||
<input type="hidden" name="ReturnUrl" value="@Model.ReturnUrl" />
|
||||
|
||||
@Html.AntiForgeryToken()
|
||||
</form>
|
||||
@ -68,7 +69,7 @@
|
||||
@foreach (var description in Model.ExternalProviders) {
|
||||
<form action="/signin" method="post">
|
||||
<input type="hidden" name="Provider" value="@description.AuthenticationScheme" />
|
||||
<input type="hidden" name="AfterLoginRedirectUrl" value="@Model.AfterLoginRedirectUrl" />
|
||||
<input type="hidden" name="ReturnUrl" value="@Url.Action("ExternalLoginCallback","Account", new { returnUrl = Model.ReturnUrl })" />
|
||||
<button class="btn btn-lg btn-success" type="submit">@SR["Connect using"] @description.DisplayName</button>
|
||||
@Html.AntiForgeryToken()
|
||||
</form>
|
||||
|
@ -13,6 +13,14 @@
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
|
||||
|
||||
<form enctype="application/x-www-form-urlencoded" method="post" class="navbar-right">
|
||||
@Html.AntiForgeryToken()
|
||||
<label for="username">username:</label><input name="username" placeholder="(Votre Nom d'utilisateur)"/>
|
||||
<label for="password">password:</label><input name="password" placeholder="(Votre mot de passe)" type="password"/>
|
||||
<input formaction="/api/token/post" class="btn btn-lg btn-success" name="Getatoken" type="submit" value="Getatoken" />
|
||||
</form>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
16
Yavsc/Views/Shared/getatoken.cshtml
Normal file
16
Yavsc/Views/Shared/getatoken.cshtml
Normal file
@ -0,0 +1,16 @@
|
||||
@using AspNet.Security.OpenIdConnect.Extensions
|
||||
@using Microsoft.IdentityModel.Protocols.OpenIdConnect
|
||||
|
||||
|
||||
@model AuthorisationView
|
||||
|
||||
<div class="jumbotron">
|
||||
<h1>Authorization</h1>
|
||||
|
||||
<p class="lead text-left">Get a token</p>
|
||||
|
||||
<form enctype="application/x-www-form-urlencoded" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<input formaction="/api/token/get" class="btn btn-lg btn-success" name="Getatoken" type="submit" value="Getatoken" />
|
||||
</form>
|
||||
</div>
|
@ -72,6 +72,7 @@
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.Authentication.Facebook": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.Authentication.Twitter": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.Authentication.Google": "1.0.0-rc1-final",
|
||||
"Microsoft.Extensions.Localization": "1.0.0-rc1-final",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "1.0.0-rc1-final",
|
||||
"Microsoft.Extensions.Globalization.CultureInfoCache": "1.0.0-rc1-final",
|
||||
@ -82,7 +83,6 @@
|
||||
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc1-final",
|
||||
"Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.Session": "1.0.0-rc1-final",
|
||||
"Microsoft.NETCore.Platforms": "1.0.1-beta-23516",
|
||||
"Microsoft.AspNet.SignalR.JS": "2.2.0",
|
||||
"Microsoft.AspNet.WebSockets.Server": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.Http.Abstractions": "1.0.0-rc1-final",
|
||||
@ -90,8 +90,6 @@
|
||||
"Microsoft.AspNet.Owin": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNet.SignalR.Core": "2.2.0",
|
||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "0.0.1-alpha",
|
||||
"Microsoft.AspNetCore.Authentication.Cookies": "0.0.1-alpha",
|
||||
"Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-rc1-final",
|
||||
"MailKit": "1.3.0-beta7",
|
||||
"Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8",
|
||||
@ -101,8 +99,6 @@
|
||||
"Microsoft.AspNet.Web.Optimization": "1.1.3",
|
||||
"PayPalCoreSDK": "1.7.1",
|
||||
"Microsoft.Extensions.WebEncoders.Core": "1.0.0-rc1-final",
|
||||
"Microsoft.AspNetCore.Authentication.OAuth": "0.0.1-alpha",
|
||||
"Microsoft.Extensions.Options": "0.0.1-alpha",
|
||||
"Microsoft.Extensions.WebEncoders": "1.0.0-rc1-final",
|
||||
"Google.Apis.Core": "1.11.1",
|
||||
"Google.Apis": "1.11.1",
|
||||
@ -113,7 +109,8 @@
|
||||
"System.IdentityModel.Tokens": "5.0.0-rc1-211161024",
|
||||
"System.IdentityModel.Tokens.Jwt": "5.0.0-rc1-211161024",
|
||||
"Microsoft.AspNet.Authorization": "1.0.0-rc1-final",
|
||||
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4"
|
||||
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4",
|
||||
"Microsoft.Extensions.Options": "0.0.1-alpha"
|
||||
},
|
||||
"commands": {
|
||||
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000",
|
||||
@ -149,4 +146,4 @@
|
||||
"prepublish": "gulp min",
|
||||
"postpublish": "./postPublish.sh"
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -28,9 +28,9 @@ namespace Yavsc.Auth
|
||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Google authentication capabilities.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="GoogleOptions"/> that specifies options for the middleware.</param>
|
||||
/// <param name="options">A <see cref="YavscGoogleOptions"/> that specifies options for the middleware.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app, GoogleOptions options)
|
||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app, YavscGoogleOptions options)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
internal class GoogleHandler : OAuthHandler<GoogleOptions>
|
||||
internal class GoogleHandler : OAuthHandler<YavscGoogleOptions>
|
||||
{
|
||||
private ILogger _logger;
|
||||
public GoogleHandler(HttpClient httpClient,ILogger logger)
|
||||
|
@ -14,7 +14,7 @@ namespace Yavsc.Auth
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using Google OAuth 2.0.
|
||||
/// </summary>
|
||||
public class GoogleMiddleware : OAuthMiddleware<GoogleOptions>
|
||||
public class GoogleMiddleware : OAuthMiddleware<YavscGoogleOptions>
|
||||
{
|
||||
private RequestDelegate _next;
|
||||
private ILogger _logger;
|
||||
@ -34,7 +34,7 @@ namespace Yavsc.Auth
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
GoogleOptions options)
|
||||
YavscGoogleOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
|
||||
{
|
||||
if (next == null)
|
||||
@ -71,7 +71,7 @@ namespace Yavsc.Auth
|
||||
|
||||
}
|
||||
|
||||
protected override AuthenticationHandler<GoogleOptions> CreateHandler()
|
||||
protected override AuthenticationHandler<YavscGoogleOptions> CreateHandler()
|
||||
{
|
||||
return new GoogleHandler(Backchannel,_logger);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
public static class GoogleDefaults
|
||||
public static class YavscGoogleDefaults
|
||||
{
|
||||
public const string AuthenticationScheme = "Google";
|
||||
|
||||
@ -17,19 +17,19 @@ namespace Yavsc.Auth
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="GoogleMiddleware"/>.
|
||||
/// </summary>
|
||||
public class GoogleOptions : OAuthOptions
|
||||
public class YavscGoogleOptions : OAuthOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="GoogleOptions"/>.
|
||||
/// Initializes a new <see cref="YavscGoogleOptions"/>.
|
||||
/// </summary>
|
||||
public GoogleOptions()
|
||||
public YavscGoogleOptions()
|
||||
{
|
||||
AuthenticationScheme = GoogleDefaults.AuthenticationScheme;
|
||||
AuthenticationScheme = YavscGoogleDefaults.AuthenticationScheme;
|
||||
DisplayName = AuthenticationScheme;
|
||||
CallbackPath = new PathString("/signin-google");
|
||||
AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = GoogleDefaults.TokenEndpoint;
|
||||
UserInformationEndpoint = GoogleDefaults.UserInformationEndpoint;
|
||||
AuthorizationEndpoint = YavscGoogleDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = YavscGoogleDefaults.TokenEndpoint;
|
||||
UserInformationEndpoint = YavscGoogleDefaults.UserInformationEndpoint;
|
||||
Scope.Add("openid");
|
||||
Scope.Add("profile");
|
||||
Scope.Add("email");
|
||||
|
42
Yavsc/src/Auth/MonoJwtSecurityTokenHandler.cs
Normal file
42
Yavsc/src/Auth/MonoJwtSecurityTokenHandler.cs
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
using System;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
|
||||
public class MonoJwtSecurityTokenHandler : JwtSecurityTokenHandler
|
||||
{
|
||||
|
||||
MonoDataProtectionProvider protectionProvider;
|
||||
public MonoJwtSecurityTokenHandler(MonoDataProtectionProvider prpro)
|
||||
{
|
||||
protectionProvider = prpro;
|
||||
}
|
||||
public override JwtSecurityToken CreateToken(
|
||||
string issuer,
|
||||
string audience, ClaimsIdentity subject,
|
||||
DateTime? notBefore, DateTime? expires, DateTime? issuedAt,
|
||||
SigningCredentials signingCredentials
|
||||
)
|
||||
{
|
||||
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Audience = audience,
|
||||
Claims = subject.Claims,
|
||||
Expires = expires,
|
||||
IssuedAt = issuedAt,
|
||||
Issuer = issuer,
|
||||
NotBefore = notBefore,
|
||||
SigningCredentials = signingCredentials
|
||||
};
|
||||
var token = base.CreateToken(tokenDescriptor);
|
||||
return token as JwtSecurityToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,8 +4,21 @@ namespace Yavsc
|
||||
{
|
||||
public class TokenAuthOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Public's identification
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Audience { get; set; }
|
||||
/// <summary>
|
||||
/// Identity authority
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Issuer { get; set; }
|
||||
/// <summary>
|
||||
/// Signin key and signature algotythm
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SigningCredentials SigningCredentials { get; set; }
|
||||
public int ExpiresIn { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
using Microsoft.AspNet.Identity;
|
||||
@ -16,6 +17,7 @@ namespace Yavsc.Auth {
|
||||
|
||||
public Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser> manager, ApplicationUser user)
|
||||
{
|
||||
if ( user==null ) throw new InvalidOperationException("no user");
|
||||
var por = new MonoDataProtector(Constants.ApplicationName,new string[] { purpose } );
|
||||
|
||||
return Task.FromResult(por.Protect(UserStamp(user)));
|
||||
@ -29,7 +31,7 @@ namespace Yavsc.Auth {
|
||||
return Task.FromResult ( user.Id == values[0] && user.Email == values[1] && user.UserName == values[2]);
|
||||
}
|
||||
|
||||
public string UserStamp(ApplicationUser user) {
|
||||
public static string UserStamp(ApplicationUser user) {
|
||||
return $"{user.Id} {user.Email} {user.UserName}";
|
||||
}
|
||||
}
|
||||
|
@ -55,8 +55,7 @@ namespace Yavsc.Controllers
|
||||
public IActionResult Login(string returnUrl)
|
||||
{
|
||||
return View("SignIn", new LoginViewModel {
|
||||
AfterLoginRedirectUrl = returnUrl,
|
||||
ReturnUrl = "/Account/ExternalLoginCallback",
|
||||
ReturnUrl = returnUrl,
|
||||
ExternalProviders = HttpContext.GetExternalProviders()
|
||||
});
|
||||
}
|
||||
|
@ -50,16 +50,15 @@ namespace Yavsc.Controllers
|
||||
|
||||
|
||||
[HttpGet("~/signin")]
|
||||
public ActionResult SignIn(string returnUrl = null, string target = null)
|
||||
public ActionResult SignIn(string returnUrl = null)
|
||||
{
|
||||
_logger.LogWarning($"Singin wanted: returnUrl: {returnUrl} target: {target}");
|
||||
_logger.LogWarning($"Singin wanted: returnUrl: {returnUrl} ");
|
||||
// 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,
|
||||
AfterLoginRedirectUrl = target,
|
||||
ExternalProviders = HttpContext.GetExternalProviders()
|
||||
});
|
||||
/* Note: When using an external login provider, redirect the query :
|
||||
@ -71,7 +70,7 @@ namespace Yavsc.Controllers
|
||||
[HttpGet("~/authenticate")]
|
||||
public ActionResult Authenticate(string returnUrl = null)
|
||||
{
|
||||
return SignIn("/Account/ExternalLoginCallback",returnUrl);
|
||||
return SignIn(returnUrl);
|
||||
}
|
||||
|
||||
[HttpGet("~/forbidden")]
|
||||
@ -81,7 +80,7 @@ namespace Yavsc.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("~/signin")]
|
||||
public IActionResult SignIn(string Provider, string ReturnUrl, string AfterLoginRedirectUrl)
|
||||
public IActionResult SignIn(string Provider, string ReturnUrl)
|
||||
{
|
||||
// Note: the "provider" parameter corresponds to the external
|
||||
// authentication provider choosen by the user agent.
|
||||
@ -97,7 +96,6 @@ namespace Yavsc.Controllers
|
||||
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
|
||||
@ -107,26 +105,13 @@ namespace Yavsc.Controllers
|
||||
// the redirect_uri of the requesting client application.
|
||||
if (string.IsNullOrEmpty(ReturnUrl))
|
||||
{
|
||||
|
||||
// If AfterLoginRedirectUrl is non null,
|
||||
// This is a web interface access,
|
||||
/// Assert (model.ReturnUrl==null)
|
||||
/// and the wanted redirection
|
||||
// after the successfull authentication
|
||||
if (AfterLoginRedirectUrl != null)
|
||||
{
|
||||
ReturnUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = AfterLoginRedirectUrl });
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("ReturnUrl not specified");
|
||||
return HttpBadRequest();
|
||||
}
|
||||
}
|
||||
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, ReturnUrl);
|
||||
|
||||
return new ChallengeResult(Provider, properties);
|
||||
|
||||
return new ChallengeResult(Provider, new AuthenticationProperties {
|
||||
RedirectUri = Url.Action("ExternalLoginCallback","Account", new {returnUrl= ReturnUrl})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +183,7 @@ namespace Yavsc.Controllers
|
||||
{
|
||||
return new ChallengeResult(new AuthenticationProperties
|
||||
{
|
||||
RedirectUri = request.BuildRedirectUrl()
|
||||
RedirectUri = Url.Action("ExternalLoginCallback","Account",new {returnUrl=request.BuildRedirectUrl()})
|
||||
});
|
||||
}
|
||||
// Note: ASOS automatically ensures that an application corresponds to the client_id specified
|
||||
@ -253,17 +238,13 @@ namespace Yavsc.Controllers
|
||||
// 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(OpenIdConnectConstants.TokenTypes.Bearer);
|
||||
claim.WithDestination( "code");
|
||||
claim.WithDestination("id_token");
|
||||
}
|
||||
|
||||
identity.AddClaim(claim);
|
||||
}
|
||||
|
||||
|
121
Yavsc/src/Controllers/TokenController.cs
Normal file
121
Yavsc/src/Controllers/TokenController.cs
Normal file
@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using System.Security.Principal;
|
||||
using Microsoft.AspNet.Authentication.JwtBearer;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
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 bool authenticated { get; set; }
|
||||
public string user_id { get; set; }
|
||||
public string access_token { get; set; }
|
||||
public int expires_in { 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,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(user, tokenExpires);
|
||||
return new TokenResponse { authenticated = authenticated, user_id = user, entity_id = entityId, access_token = token, expires_in = 3400 };
|
||||
|
||||
}
|
||||
}
|
||||
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(User.GetUserId(), expires);
|
||||
return Ok(new TokenResponse { authenticated = true, user_id = User.GetUserId(), access_token = token });
|
||||
}
|
||||
return Ok(new TokenResponse { authenticated = false });
|
||||
}
|
||||
|
||||
private async Task<string> GetToken(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("id_token",manager,identuser);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
29
Yavsc/src/Controllers/ValuesController.cs
Normal file
29
Yavsc/src/Controllers/ValuesController.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class ValuesController : Controller
|
||||
{
|
||||
// GET: api/values
|
||||
[HttpGet]
|
||||
public IEnumerable<string> Get()
|
||||
{
|
||||
//throw new Exception("Horsed");
|
||||
return new string[] { "value1", "value2" };
|
||||
}
|
||||
|
||||
// GET api/values/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize("Bearer")]
|
||||
public string Get(int id)
|
||||
{
|
||||
return "value";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using AspNet.Security.OpenIdConnect.Extensions;
|
||||
using AspNet.Security.OpenIdConnect.Server;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Yavsc.Auth;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Providers {
|
||||
public sealed class AuthorizationProvider : OpenIdConnectServerProvider {
|
||||
|
||||
private ILogger _logger;
|
||||
UserTokenProvider tokenProvider;
|
||||
UserManager<ApplicationUser> userManager;
|
||||
|
||||
SignInManager<ApplicationUser> signInManager;
|
||||
|
||||
public AuthorizationProvider(ILoggerFactory loggerFactory) {
|
||||
public AuthorizationProvider(ILoggerFactory loggerFactory, UserTokenProvider tokenProvider) {
|
||||
_logger = loggerFactory.CreateLogger<AuthorizationProvider>();
|
||||
this.tokenProvider = tokenProvider;
|
||||
}
|
||||
public override Task MatchEndpoint(MatchEndpointContext context) {
|
||||
// Note: by default, OpenIdConnectServerHandler only handles authorization requests made to the authorization endpoint.
|
||||
@ -129,5 +137,14 @@ namespace Yavsc.Providers {
|
||||
_logger.LogWarning($"OIDC success : IsAccessToken: {context.AuthenticationTicket.IsAccessToken()}");
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
/*
|
||||
|
||||
public override async Task SerializeAccessToken(SerializeAccessTokenContext context)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(context.HttpContext.User.GetUserId());
|
||||
context.AccessToken = await tokenProvider.GenerateAsync("id_token",userManager,user);
|
||||
context.HandleResponse();
|
||||
return ;
|
||||
} */
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ using System.Web.Optimization;
|
||||
using AspNet.Security.OpenIdConnect.Extensions;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.Cookies;
|
||||
using Microsoft.AspNet.Authentication.Google;
|
||||
using Microsoft.AspNet.Authentication.JwtBearer;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
@ -35,7 +36,6 @@ using Microsoft.Extensions.PlatformAbstractions;
|
||||
using Microsoft.Extensions.WebEncoders;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Yavsc.Auth;
|
||||
using Yavsc.Extensions;
|
||||
using Yavsc.Formatters;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Providers;
|
||||
@ -161,7 +161,7 @@ namespace Yavsc
|
||||
{
|
||||
options.SignInScheme = "ServerCookie";
|
||||
});
|
||||
/*
|
||||
|
||||
services.Configure<TokenAuthOptions>(
|
||||
to =>
|
||||
{
|
||||
@ -169,9 +169,9 @@ namespace Yavsc
|
||||
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>)));
|
||||
@ -179,6 +179,9 @@ namespace Yavsc
|
||||
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>)));
|
||||
|
||||
|
||||
services.AddTransient<Microsoft.Extensions.WebEncoders.UrlEncoder, UrlEncoder>();
|
||||
services.AddDataProtection();
|
||||
services.Add(ServiceDescriptor.Singleton(typeof(IApplicationDiscriminator),
|
||||
@ -206,6 +209,7 @@ namespace Yavsc
|
||||
option.User.RequireUniqueEmail = true;
|
||||
option.Cookies.ApplicationCookie.DataProtectionProvider =
|
||||
new MonoDataProtectionProvider(Configuration["Site:Title"]);
|
||||
option.Cookies.ApplicationCookie.CookieName = "Bearer";
|
||||
}
|
||||
).AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddTokenProvider<EmailTokenProvider<ApplicationUser>>(Constants.EMailFactor)
|
||||
@ -213,7 +217,7 @@ namespace Yavsc
|
||||
;
|
||||
// .AddTokenProvider<UserTokenProvider>(Constants.SMSFactor)
|
||||
//
|
||||
|
||||
|
||||
services.AddCors(
|
||||
/*
|
||||
options =>
|
||||
@ -242,11 +246,9 @@ namespace Yavsc
|
||||
});
|
||||
|
||||
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("Bearer",new AuthorizationPolicyBuilder()
|
||||
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
|
||||
.RequireAuthenticatedUser().Build());
|
||||
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
||||
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
|
||||
// options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
||||
@ -259,6 +261,7 @@ namespace Yavsc
|
||||
services.AddSingleton<IAuthorizationHandler, CommandEditHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, CommandViewHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, PostUserFileHandler>();
|
||||
|
||||
services.AddMvc(config =>
|
||||
{
|
||||
var policy = new AuthorizationPolicyBuilder()
|
||||
@ -302,8 +305,9 @@ namespace Yavsc
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
|
||||
IOptions<SiteSettings> siteSettings, IOptions<RequestLocalizationOptions> localizationOptions,
|
||||
IOptions<OAuth2AppSettings> oauth2SettingsContainer,
|
||||
IOptions<SiteSettings> siteSettings,
|
||||
IOptions<RequestLocalizationOptions> localizationOptions,
|
||||
IOptions<OAuth2AppSettings> oauth2SettingsContainer,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
Startup.UserFilesDirName = siteSettings.Value.UserFiles.DirName;
|
||||
@ -354,16 +358,20 @@ namespace Yavsc
|
||||
}
|
||||
}
|
||||
|
||||
app.UseIISPlatformHandler(
|
||||
options => options.AuthenticationDescriptions.Clear()
|
||||
);
|
||||
|
||||
var googleOptions = new GoogleOptions
|
||||
var googleOptions = new YavscGoogleOptions
|
||||
{
|
||||
ClientId = Configuration["Authentication:Google:ClientId"],
|
||||
ClientSecret = Configuration["Authentication:Google:ClientSecret"],
|
||||
AccessType = "offline",
|
||||
/* AccessType = "offline",
|
||||
SaveTokensAsClaims = true,
|
||||
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me",
|
||||
UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me",*/
|
||||
AutomaticAuthenticate=true,
|
||||
AutomaticChallenge=true
|
||||
};
|
||||
|
||||
var gvents = new OAuthEvents();
|
||||
|
||||
googleOptions.Events = new OAuthEvents
|
||||
@ -384,12 +392,6 @@ namespace Yavsc
|
||||
|
||||
googleOptions.Scope.Add("https://www.googleapis.com/auth/calendar");
|
||||
|
||||
app.UseIISPlatformHandler(options =>
|
||||
{
|
||||
options.AuthenticationDescriptions.Clear();
|
||||
options.AutomaticAuthentication = true;
|
||||
});
|
||||
|
||||
app.UseFileServer(new FileServerOptions()
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(
|
||||
@ -404,16 +406,17 @@ namespace Yavsc
|
||||
EnableDirectoryBrowsing = false
|
||||
});
|
||||
app.UseStaticFiles().UseWebSockets();
|
||||
|
||||
app.UseIdentity();
|
||||
app.UseOpenIdConnectServer(options =>
|
||||
{
|
||||
options.Provider = new AuthorizationProvider(loggerFactory);
|
||||
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.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
|
||||
@ -421,6 +424,7 @@ namespace Yavsc
|
||||
options.ApplicationCanDisplayErrors = true;
|
||||
options.AllowInsecureHttp = true;
|
||||
options.AutomaticChallenge = true;
|
||||
|
||||
options.AuthorizationEndpointPath = new PathString("/connect/authorize");
|
||||
options.TokenEndpointPath = new PathString("/connect/authorize/accept");
|
||||
options.UseSlidingExpiration = true;
|
||||
@ -428,54 +432,32 @@ namespace Yavsc
|
||||
options.AuthenticationScheme = "ServerCookie"; // was = OpenIdConnectDefaults.AuthenticationScheme || "oidc";
|
||||
options.LogoutEndpointPath = new PathString("/connect/logout");
|
||||
|
||||
/* options.ValidationEndpointPath = new PathString("/connect/introspect"); */
|
||||
});
|
||||
// options.ValidationEndpointPath = new PathString("/connect/introspect");
|
||||
}); /**/
|
||||
|
||||
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>
|
||||
{
|
||||
branch.UseIdentity();
|
||||
|
||||
branch.UseJwtBearerAuthentication(options =>
|
||||
{
|
||||
options.AutomaticAuthenticate = true;
|
||||
options.AutomaticChallenge = true;
|
||||
options.RequireHttpsMetadata = false;
|
||||
options.Audience = siteSettings.Value.Audience;
|
||||
options.Authority = siteSettings.Value.Authority;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Create a new branch where the registered middleware will be executed only for API calls.
|
||||
app.UseWhen(context => !context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>
|
||||
{
|
||||
branch.UseIdentity();
|
||||
branch.UseCookieAuthentication(options =>
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
options.AutomaticAuthenticate = true;
|
||||
options.AutomaticChallenge = true;
|
||||
options.AuthenticationScheme = "ServerCookie";
|
||||
options.CookieName = CookieAuthenticationDefaults.CookiePrefix + "ServerCookie";
|
||||
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
||||
options.LoginPath = new PathString("/signin");
|
||||
options.LogoutPath = new PathString("/signout");
|
||||
options.ReturnUrlParameter = "target";
|
||||
});
|
||||
|
||||
branch.UseMiddleware<GoogleMiddleware>(googleOptions);
|
||||
app.UseMiddleware<Yavsc.Auth.GoogleMiddleware>(googleOptions);
|
||||
|
||||
// Facebook
|
||||
branch.UseFacebookAuthentication(options =>
|
||||
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.UseRequestLocalization(localizationOptions.Value, (RequestCulture)new RequestCulture((string)"fr"));
|
||||
|
||||
/* Generic OAuth (here GitHub): options.Notifications = new OAuthAuthenticationNotifications
|
||||
|
@ -23,12 +23,6 @@ namespace Yavsc.ViewModels.Account
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ReturnUrl { get; set; }
|
||||
/// <summary>
|
||||
/// This is the Url redirection used after a successfull resource grant
|
||||
/// to a legacy web browser client.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string AfterLoginRedirectUrl { get; set; }
|
||||
|
||||
public IEnumerable<AuthenticationDescription> ExternalProviders { get; set; }
|
||||
}
|
||||
|
Reference in New Issue
Block a user