登录后MVC应用程序重定向到错误页面,我不明白为什么

时间:2018-04-23 00:39:58

标签: c# asp.net asp.net-mvc azure azure-web-sites

我有一个MVC应用程序,要求用户使用他的microsoft帐户登录,并且在localhost上测试时工作正常,但是在将其发布到Azure时,登录后用户会被重定向到http://{appname}.azurewebsites.net/home/error,由于我没有在我的家庭控制器上实现错误方法,导致找不到404。我的问题是,我不知道是什么原因导致应用程序重定向到此错误页面。尝试在浏览器上手动输入http://{appname}.azurewebsites.net/home,只需重新定向到错误页面。

我尝试在家庭控制器上创建一个错误方法,只显示一个"你好"在屏幕上发生了一些非常奇怪的事情,应用程序在错误页面网址和Windows登录页面之间来回重定向,而没有实际打开(我可以看到网址在浏览器上来回切换,但两个页面都没有打开,因为它在加载完成之前重定向。)

然后我将主控制器上的方法基本上留空了,如下所示,只剩下Visual Studio剩下的默认内容,但同样的问题仍然存在。

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";

        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }
}

在web.config上我有<customErrors mode="Off"/>,所以我右键单击了错误页面并单击了show source,并在html之后列出了这个异常堆栈跟踪:

[HttpException]: A public action method &#39;Error&#39; was not found on controller &#39;LogDatabaseApi.Controllers.HomeController&#39;.
   at System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

但这似乎只是说家庭控制器中的错误方法没有找到,它没有说明为什么应用程序首先重定向到错误页面。我实际上在一个完美运行的同一个Web应用程序中有一个API控制器(不需要授权)。家庭控制器在localhost上完美运行,它只是在Azure上做了所有这些奇怪的事情。

编辑:Startup.Auth.cs

public partial class Startup
{
    private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
    private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
    private string resourceEndPoint = "https://manage.office.com";
    private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
    private string authority = aadInstance + "common";
    private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];

    public void ConfigureAuth(IAppBuilder app)
    {

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions { });

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                RedirectUri = redirectUri,
                PostLogoutRedirectUri = redirectUri,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                        // instead of using the default validation (validating against a single issuer value, as we do in line of business apps), 
                        // we inject our own multitenant validation logic
                        ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    SecurityTokenValidated = (context) =>
                    {
                        return Task.FromResult(0);
                    },
                    AuthorizationCodeReceived = (context) =>
                    {
                        var code = context.Code;

                        ClientCredential credential = new ClientCredential(clientId, appKey);
                        string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

                        AuthenticationContext authContext = new AuthenticationContext(aadInstance + tenantID, new ADALTokenCache(signedInUserID));
                        AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, resourceEndPoint);

                        AdminLogin.AdminOrganization = new Organization
                        {
                            Id = Guid.Parse(tenantID),
                            Name = "Unknown",
                            AccessToken = result.AccessToken,
                            TokenExpiration = result.ExpiresOn.DateTime,
                            RefreshToken = result.RefreshToken
                        };

                        return Task.FromResult(0);
                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.OwinContext.Response.Redirect("/Home/Error");
                        context.HandleResponse(); // Suppress the exception
                            return Task.FromResult(0);
                    }
                }
            });

    }
}

1 个答案:

答案 0 :(得分:0)

显然OWIN没有正确检测启动类并抛出导致整个问题的异常。将<add key="owin:AutomaticAppStartup" value="false" />添加到web.config文件中的appsettings解决了问题