ASP.NET MVC OIDC - 如何在 cookie/token 过期时重定向到主控制器和操作

问题描述

我正在使用 OIDC 授权用户访问我组织内的 ASP.NET MVC 应用程序。

我遇到的问题是我的回复 URL 如下https://mywebsite.net/

每次 cookie/令牌过期并且用户导航到非认控制器 https://mywebsite.net/Home/Index 时都会遇到此 OIDC 错误

AADSTS50011:请求中指定的回复 URL 与为应用程序配置的回复 URL 不匹配

有什么方法可以捕获此错误,而无需将所有控制器和操作添加回复 URL 中?

我可以说捕获此错误并尝试尝试通过主页/索引登录用户吗?

这是我的路由配置:

public static void RegisterRoutes(RouteCollection routes)
{
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home",action = "Index",id = UrlParameter.Optional },new[] { "FAT_Manager.Controllers" }
        );
}

这是我的 OIDC 代码

public void ConfigureAuth(IAppBuilder app)
{
        FATContext db = new FATContext();

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationoptions
        {
            AuthenticationType = "Cookies",CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),//ExpireTimeSpan = System.TimeSpan.FromMinutes(1),});

        app.USEOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationoptions
            {
                ClientId = clientId,Authority = Authority,PostlogoutRedirectUri = postlogoutRedirectUri,TokenValidationParameters = new TokenValidationParameters
                {
                    // we inject our own multitenant validation logic
                    ValidateIssuer = false,// map the claimsPrincipal's roles to the roles claim
                    RoleClaimType = "groups",NameClaimType = "preferred_username",},MetadataAddress = "MetaAddressHere",Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        // This ensures that the address used for sign in and sign out is picked up dynamically from the request
                        // this allows you to deploy your app (to Azure Web Sites,for example) without having to change settings
                        // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
                        //string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
                        context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
                        context.ProtocolMessage.PostlogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action("Index","Home",null,HttpContext.Current.Request.Url.Scheme);
                        return Task.Fromresult(0);
                    },// If there is a code in the OpenID Connect response,redeem it for an access token and refresh token,and store those away.
                    AuthorizationCodeReceived = (context) =>
                    {
                        var code = context.Code;
                       
                        ClientCredential credential = new ClientCredential(clientId,appKey);
                        string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                        AuthenticationContext authContext = new AuthenticationContext(Authority,new ADALTokenCache(signedInUserID));
                        return authContext.AcquiretokenByAuthorizationCodeAsync(
                           code,new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),credential,graphResourceId);
                    }
                }
            });
}

解决方法

找到答案

更改了这一行:

context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);

致:

context.ProtocolMessage.RedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action("Index","Home",null,HttpContext.Current.Request.Url.Scheme);