oauth
This commit is contained in:
@ -50,18 +50,62 @@ namespace Yavsc.Controllers
|
||||
_twilioSettings = twilioSettings.Value;
|
||||
_logger = loggerFactory.CreateLogger<AccountController>();
|
||||
}
|
||||
|
||||
[HttpGet("~/login")]
|
||||
public IActionResult Login(string returnUrl)
|
||||
[HttpGet(Constants.LoginPath)]
|
||||
public ActionResult Login(string returnUrl = null)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
@ -92,6 +136,7 @@ namespace Yavsc.Controllers
|
||||
ModelState.AddModelError(string.Empty, "Unexpected behavior: something failed ... you could try again, or contact me ...");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/Register
|
||||
[HttpGet]
|
||||
@ -131,7 +176,7 @@ namespace Yavsc.Controllers
|
||||
|
||||
//
|
||||
// POST: /Account/LogOff
|
||||
[HttpPost]
|
||||
[HttpPost(Constants.LogoutPath)]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> LogOff(string returnUrl = null)
|
||||
{
|
||||
@ -140,18 +185,6 @@ namespace Yavsc.Controllers
|
||||
if (returnUrl==null) return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
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
|
||||
|
@ -1,34 +1,40 @@
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.DataProtection.KeyManagement;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.AspNet.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Yavsc.Extensions;
|
||||
using OAuth.AspNet.AuthServer;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.ViewModels.Account;
|
||||
|
||||
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]
|
||||
public class OAuthController : Controller
|
||||
{
|
||||
ApplicationDbContext _context;
|
||||
UserManager<ApplicationUser> _userManager;
|
||||
|
||||
|
||||
SiteSettings _siteSettings;
|
||||
|
||||
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,
|
||||
IOptions<SiteSettings> siteSettings,
|
||||
ILoggerFactory loggerFactory
|
||||
@ -37,90 +43,61 @@ namespace Yavsc.Controllers
|
||||
_siteSettings = siteSettings.Value;
|
||||
_context = context;
|
||||
_signInManager = signInManager;
|
||||
_tokenOptions = tokenOptions.Value;
|
||||
_userManager = userManager;
|
||||
_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)
|
||||
{
|
||||
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
|
||||
// authentication provider choosen by the user agent.
|
||||
if (string.IsNullOrEmpty(Provider))
|
||||
{
|
||||
_logger.LogWarning("Provider not specified");
|
||||
return HttpBadRequest();
|
||||
}
|
||||
// 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 _userManager.FindByIdAsync(userid);
|
||||
|
||||
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();
|
||||
}
|
||||
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);
|
||||
return await _tokenProvider.GenerateAsync(purpose, _userManager, identuser);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("~/signout"), HttpPost("~/signout")]
|
||||
public async Task SignOut()
|
||||
/// <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("~/oauth/token")]
|
||||
public async Task<dynamic> Get()
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
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 };
|
||||
} */
|
||||
|
||||
|
||||
[HttpGet("~/api/getclaims"), Produces("application/json")]
|
||||
@ -140,14 +117,66 @@ namespace Yavsc.Controllers
|
||||
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.
|
||||
return (from application in _context.Applications
|
||||
where application.ApplicationID == identifier
|
||||
select application).SingleOrDefaultAsync(cancellationToken);
|
||||
if (Response.StatusCode != 200)
|
||||
{
|
||||
return View("AuthorizeError");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user