Answered by:
ASP.NET MVC 5 - Microsoft Account OAuth2 sign-on is returning “error=access_denied” when a valid domain is used instead of localhost

Question
-
User-269243710 posted
I have implemented a very simple OAuth2 sign-on for Microsoft and Google accounts (See: Startup.Auth.cs and AccountController.cs) and I am facing an issue for authenticate when I am using the Microsoft authentication with a valid domain (e.g.: http://mydomain.ddns.net/IRIS/Account/Login?ReturnUrl=%2FIRIS%2F):
- error=access_denied
Note that if I try to authenticate using the localhost instead of mydomain.ddns.net (e.g.: http://localhost/IRIS/Account/Login?ReturnUrl=%2FIRIS%2F) the Microsoft authentication works perfect!
Other important info is that for both cases, localhost and mydomain.ddns.net, the Google authentication is working without any issue!
From Application Registration Portal I could not identify any issue once that http://mydomain.ddns.net/IRIS/signin-microsoft and http://localhost/IRIS/signin-microsoft are registered as Redirect URIs.
Some of you have faced a similar problem? I really appreciate if any of you help me for fixing this issue :)
Startup.Auth.cs
using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.Google; using Microsoft.Owin.Security.MicrosoftAccount; using Owin; namespace IRIS { public partial class Startup { private void ConfigureAuth(IAppBuilder app) { var cookieAuthenticationOptions = new CookieAuthenticationOptions { ExpireTimeSpan = System.TimeSpan.FromMinutes(30), LoginPath = new PathString("/Account/Login") }; app.UseCookieAuthentication(cookieAuthenticationOptions); app.SetDefaultSignInAsAuthenticationType(cookieAuthenticationOptions.AuthenticationType); //https://console.developers.google.com/project/iris-985/apiui/credential app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions { ClientId = "<MyGoogleClientId>", ClientSecret = "<MyGoogleClientSecret>" }); //https://apps.dev.microsoft.com/#/appList app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions { ClientId = "<MyMicrosoftClientId>", ClientSecret = "<MyMicrosoftClientSecret>", Scope = { "wl.basic", "wl.emails" } }); } } }
AccountController.cs
using Microsoft.Owin.Security; using System.Web; using System.Web.Mvc; namespace IRIS.Controllers { public class AccountController : Controller { [AllowAnonymous] [OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.None)] //Evita o seguinte erro de login: http://stackoverflow.com/questions/24376800/the-back-button-and-the-anti-forgery-token public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult GoogleLogin(string returnUrl) { return new ChallengeResult("Google", Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public ActionResult MicrosoftLogin(string returnUrl) { return new ChallengeResult("Microsoft", Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); } [AllowAnonymous] public ActionResult ExternalLoginCallback(string error, string returnUrl) { System.Web.HttpContext.Current.Response.Cookies["account"].Expires = System.DateTime.Now.AddDays(-1); string[] outputParameters = new string[4]; if ((error != "access_denied") && (Models.Data.Firebird.ExecuteProcedure("I_LOGIN", new string[] { System.Security.Claims.ClaimsPrincipal.Current.FindFirst(System.Security.Claims.ClaimTypes.Email).Value }, outputParameters))) { System.Web.HttpContext.Current.Response.Cookies["account"]["error"] = outputParameters[0]; System.Web.HttpContext.Current.Response.Cookies["account"]["userID"] = outputParameters[1]; System.Web.HttpContext.Current.Response.Cookies["account"]["userFirstName"] = outputParameters[2]; System.Web.HttpContext.Current.Response.Cookies["account"]["userFullName"] = outputParameters[3]; System.Web.HttpContext.Current.Response.Cookies["account"]["userEmail"] = System.Security.Claims.ClaimsPrincipal.Current.FindFirst(System.Security.Claims.ClaimTypes.Email).Value; System.Web.HttpContext.Current.Response.Cookies["account"].Expires = System.DateTime.Now.AddDays(1); } return outputParameters[0] != null && outputParameters[0] == "0" ? RedirectToLocal(returnUrl) : RedirectToAction("Logout", "Account", new { ReturnUrl = returnUrl }); } [AllowAnonymous] public ActionResult Logout(string returnUrl) { HttpContext.GetOwinContext().Authentication.SignOut(); return returnUrl == null ? RedirectToAction("Index", "Home") : RedirectToLocal(returnUrl); } #region Helpers private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction("Index", "Home"); } internal class ChallengeResult : HttpUnauthorizedResult { public ChallengeResult(string provider, string redirectUri) { LoginProvider = provider; RedirectUri = redirectUri; } public string LoginProvider { get; set; } public string RedirectUri { get; set; } public override void ExecuteResult(ControllerContext context) { var properties = new AuthenticationProperties { RedirectUri = RedirectUri }; context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); } } #endregion } }
Tuesday, September 20, 2016 10:07 AM
Answers
All replies
-
-
User-269243710 posted
Thank you very much Na Yu!
This was the reason why it was not working!
Best Regards,
Luciano
Wednesday, September 21, 2016 9:12 AM