Asp.net mvc 4 OWIN中间件未拦截HttpUnauthorizedResult

Asp.net mvc 4 OWIN中间件未拦截HttpUnauthorizedResult,asp.net-mvc-4,owin,openid-connect,Asp.net Mvc 4,Owin,Openid Connect,我有一个现有的项目,需要使用Open ID Connect实现SSO。我正在使用Okta测试实现,稍后将需要使用我们现有的身份验证提供商。然而,下面是我的场景 现有的MVC4项目有global.asax文件,该文件处理诸如区域注册、路由注册和注册全局过滤器等日常事务 我已经安装了所需的OWIN包,并添加了OWIN启动类 当应用程序运行时,将触发OWIN启动类,并且配置方法运行时不会出现问题 但是,当用户尝试执行SSO时,OWIN中间件不会拦截HttpUnauthorizedResult操作结果,

我有一个现有的项目,需要使用Open ID Connect实现SSO。我正在使用Okta测试实现,稍后将需要使用我们现有的身份验证提供商。然而,下面是我的场景

  • 现有的MVC4项目有global.asax文件,该文件处理诸如区域注册、路由注册和注册全局过滤器等日常事务
  • 我已经安装了所需的OWIN包,并添加了OWIN启动类
  • 当应用程序运行时,将触发OWIN启动类,并且配置方法运行时不会出现问题
  • 但是,当用户尝试执行SSO时,OWIN中间件不会拦截
    HttpUnauthorizedResult
    操作结果,从而导致应用程序返回404错误,而不是重定向到Okta以进入登录和同意屏幕
  • 下面是我看到的错误页面

    • 请查看我在相应文件中的代码
    Global.asax

    protected void Application_Start(object sender, EventArgs e)
    {
          //This piece of code is moved to startup.cs to try to resolve this issue but didn't work
          //AreaRegistration.RegisterAllAreas();
    
          //WebApiConfig.Register(GlobalConfiguration.Configuration);
          //FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
          //RouteConfig.RegisterRoutes(RouteTable.Routes);
          //log4net.Config.XmlConfigurator.Configure();
          //MvcHandler.DisableMvcResponseHeader = true;
     }
    
     protected void Application_BeginRequest(object sender, EventArgs e)
     {
            CultureInfo newCulture = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
            newCulture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
            newCulture.DateTimeFormat.DateSeparator = "/";
            Thread.CurrentThread.CurrentCulture = newCulture;
            Response.AddHeader("X-Frame-Options", "DENY");
            Response.AddHeader("X-Frame-Options", "DENY");
     }
    
    • 正如您在上面所注意到的,我删除了应用程序中的所有内容,并移到startup.cs,但这也没有解决问题
    Startup.cs

        private readonly string clientId = ConfigurationManager.AppSettings["okta:ClientId"];
        private readonly string redirectUri = ConfigurationManager.AppSettings["okta:RedirectUri"];
        private readonly string authority = ConfigurationManager.AppSettings["okta:OrgUri"];
        private readonly string clientSecret = ConfigurationManager.AppSettings["okta:ClientSecret"];
        private readonly string postLogoutRedirectUri = ConfigurationManager.AppSettings["okta:PostLogoutRedirectUri"];
        public void Configuration(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                ClientSecret = clientSecret,
                Authority = authority,
                RedirectUri = redirectUri,
                ResponseType = OpenIdConnectResponseType.CodeIdToken,
                Scope = OpenIdConnectScope.OpenIdProfile,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name"
                },
    
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthorizationCodeReceived = async n =>
                    {
                        // Exchange code for access and ID tokens
                        var tokenClient = new TokenClient(authority + "/v1/token", clientId, clientSecret);
                        var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, redirectUri);
    
                        if (tokenResponse.IsError)
                        {
                            throw new Exception(tokenResponse.Error);
                        }
    
                        var userInfoClient = new UserInfoClient(authority + "/v1/userinfo");
                        var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
                        var claims = new List<Claim>();
                        claims.AddRange(userInfoResponse.Claims);
                        claims.Add(new Claim("id_token", tokenResponse.IdentityToken));
                        claims.Add(new Claim("access_token", tokenResponse.AccessToken));
    
                        if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
                        {
                            claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken));
                        }
    
                        n.AuthenticationTicket.Identity.AddClaims(claims);
    
                        return;
                    },
    
                    RedirectToIdentityProvider = n =>
                    {
                        // If signing out, add the id_token_hint
                        if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                        {
                            var idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token");
    
                            if (idTokenClaim != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenClaim.Value;
                            }
    
                        }
    
                        return Task.CompletedTask;
                    }
                },
            });
    
            AreaRegistration.RegisterAllAreas();
    
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            log4net.Config.XmlConfigurator.Configure();
            MvcHandler.DisableMvcResponseHeader = true;
    
        }
    
    另外,需要注意的是,我在一个只有startup.cs的新项目中成功地实现了这一点,它将我重定向到Okta,通过中间件干预
    HttpUnauthorizedResult
    进行登录

    如果有人能指导我如何成功地使OWIN Interference
    HttpUnauthorizedResult
    ,我将不胜感激

     public ActionResult SingleSignOn()
     {
         if (!HttpContext.User.Identity.IsAuthenticated)
         {
             HttpContext.GetOwinContext().Authentication.
                    Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
             return new HttpUnauthorizedResult();
         }
    
         return RedirectToAction("Index", "UserAccess");
     }