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

  • 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

  • User1724605321 posted

    Hi ,

    Try to use https:// instead of http: in redirect url . 

    Best Regards,

    Nan Yu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 21, 2016 7:28 AM

All replies

  • User1724605321 posted

    Hi ,

    Try to use https:// instead of http: in redirect url . 

    Best Regards,

    Nan Yu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 21, 2016 7:28 AM
  • 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