ASP.NET 4.8 WebForms使用Owin OpenID Connect Authentication(App.UseOpenIdConnectAuthentication)授权

发布于 2025-01-23 05:28:25 字数 3942 浏览 0 评论 0原文

我遇到了login.microsoftonline.com和我的应用程序之间的无限重定向循环。我的项目是在ASP.NET 4.8 Web表单项目中实施身份验证和授权。我可以使用默认的OWIN启动文件添加身份验证,然后在Web配置文件中进行身份验证。以下功能正确,可以要求用户登录,然后才能访问pages/authrequired

startupauth.cs

public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
        private static string authority = ConfigurationManager.AppSettings["ida:Authority"];
        private static string clientSecret = ConfigurationManager.AppSettings["AppRegistrationSecret-Local"];
        public void ConfigureAuth(IAppBuilder app)
        {
            //for debugging
            //IdentityModelEventSource.ShowPII = true;

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
                    ClientSecret = clientSecret,
                    RedirectUri = postLogoutRedirectUri,
                    //This allows multitenant
                    //https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/03-authentication.md
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = false
                    },

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthenticationFailed = (context) =>
                        {
                            return Task.FromResult(0);
                        }
                    }
                }
                );

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }
    }

web.config

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <deny users="?" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

我需要添加授权,以便只有具有管理员角色的用户才能访问页面/authrequired。我已经通过更新Web配置来完成此操作:

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <allow roles="Admin" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

如果用户担任该角色,则将授权添加到身份验证的页面上正常工作,但是如果没有角色的用户尝试访问该页面,则将其重定向回到login.microsoftonline。 com,然后以无限循环返回应用程序。

我可以看到Owin UsePopenidConnectauthentication在未经授权的情况下返回302响应,这导致了循环。

我该如何更改它,以便将未经授权(但经过身份验证的)用户重新引导到登录。Microsoftonline.com,而是应该将用户定向到显示401错误的应用程序页面?

I am encountering an infinite redirect loop between login.microsoftonline.com and my application. My project is implementing authentication and authorization in an Asp.net 4.8 web forms project. I am able to add authentication using the default Owin startup file and then require authentication in the web config file. The below works correctly for requiring a user to sign in before being able to access pages/AuthRequired

StartupAuth.CS

public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
        private static string authority = ConfigurationManager.AppSettings["ida:Authority"];
        private static string clientSecret = ConfigurationManager.AppSettings["AppRegistrationSecret-Local"];
        public void ConfigureAuth(IAppBuilder app)
        {
            //for debugging
            //IdentityModelEventSource.ShowPII = true;

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,
                    ClientSecret = clientSecret,
                    RedirectUri = postLogoutRedirectUri,
                    //This allows multitenant
                    //https://github.com/Azure-Samples/guidance-identity-management-for-multitenant-apps/blob/master/docs/03-authentication.md
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = false
                    },

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthenticationFailed = (context) =>
                        {
                            return Task.FromResult(0);
                        }
                    }
                }
                );

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }
    }

Web.Config

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <deny users="?" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

I need to add authorization so that only users with the admin role will be able to access Pages/AuthRequired. I have done that by updating the web config:

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
            <authorization>
                <allow roles="Admin" />
                <deny users="*" />
            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

Adding authorization to the authenticated page works correctly if the user has that role, but if a user who doesn't have the role tries to access the page they are redirected back to login.microsoftonline.com and then back to the application in an infinite loop.

I can see that Owin UseOpenIdConnectAuthentication is returning a 302 response on unauthorized and that is causing the loop.

How can I change it so that instead of redirecting unauthorized (but authenticated) users to login.microsoftonline.com, that user should be directed to an app page that displays a 401 error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神爱温柔 2025-01-30 05:28:25

请检查以下工作是否有帮助:

通常,如果启用了表单身份验证,则在状态代码为401时将重定向到登录页面。

作为解决方法,请尝试将以下添加到Global.asax中。在“应用程序结束请求”中,如果需要,您可以创建自己的未经授权的页面,然后重定向到此。

if (this.Response.StatusCode == 302&& this.Response.StatusCode == 401 
        && this.Response.RedirectLocation.ToLower().Contains("login.aspx"))
      {
        this.Response.StatusCode = 401;
         //or Response.Redirect("Unauthorized.aspx");
      }
      

您也可以检查此&gt; 重定向未经授权的用户到ASP .NET中的消息页面。 (microsoft.com)

其他参考资料

  1. desk Redirect loginect登录状态代码401(未授权)
    (Microsoft.com)
  2. asp.net-处理(无重定向)401未经授权? -
    堆栈溢出

Please check if below work around helps:

Its usually possible that if forms authentication is enabled, you will be redirected to the login page when status code is 401.

As a workaround try Adding the below to global.asax in the application end request and you can create own unauthorized page if needed and redirect to that.

if (this.Response.StatusCode == 302&& this.Response.StatusCode == 401 
        && this.Response.RedirectLocation.ToLower().Contains("login.aspx"))
      {
        this.Response.StatusCode = 401;
         //or Response.Redirect("Unauthorized.aspx");
      }
      

You can also check this > Redirect unauthorised user to message page in ASP .Net. (microsoft.com)

Other references

  1. Prevent redirect to login on status code 401 (Unauthorized)
    (microsoft.com)
  2. asp.net - In-place handling (no redirect) of 401 unauthorized? -
    Stack Overflow
始终不够 2025-01-30 05:28:25

ASP.NET URL授权似乎与OIDC(即Azure AD)相互键入。

首先从您的web.config删除URL授权:

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
--            <authorization>
--                <allow roles="Admin" />
--                <deny users="*" />
--            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

在全球所有页面上都需要进行身份验证:

    <system.web>
      <deny users="?" />
    </system.web>

您可以使用&lt;允许用户=“?”覆盖此行为。 /&gt;对于特定页面,即登录/登录/erorr页面/等。

第二个将授权逻辑添加到您的authrequired.aspx页面:

public partial class AuthRequired {
  protected void Page_Load(object sender, EventArgs e)
  {
    Authorization.AuthorizeAuthRequiredPage();
    ...
  }
}

public static class Authorization
{
  public static void AuthorizeAuthRequiredPage()
  {
    if (!Authorized(HttpContext.User))
    {
      Redirect("/Anauthorized.aspx");
    }
  }

  private static bool Authorized(User user) => { ... }
}

ASP.NET URL Authorization doesn't appear to interoperate well with OIDC (i.e. Azure AD).

First remove the URL Authorization from your Web.config:

<configuration>
...
    <system.web>
        <authentication mode="None" />
    </system.web>
    <location path="Pages/AuthRequired">
        <system.web>
--            <authorization>
--                <allow roles="Admin" />
--                <deny users="*" />
--            </authorization>
        </system.web>
    </location>
    <system.webServer>
        <modules>
            <remove name="FormsAuthentication" />
        </modules>
    </system.webServer>
...
</configuration>

Optionally make authenticated required for all pages globally:

    <system.web>
      <deny users="?" />
    </system.web>

You can override this behaviour with <Allow users="?" /> for specific pages i.e. logins/logouts/erorr pages/etc.

Second add authorization logic to your AuthRequired.aspx page:

public partial class AuthRequired {
  protected void Page_Load(object sender, EventArgs e)
  {
    Authorization.AuthorizeAuthRequiredPage();
    ...
  }
}

public static class Authorization
{
  public static void AuthorizeAuthRequiredPage()
  {
    if (!Authorized(HttpContext.User))
    {
      Redirect("/Anauthorized.aspx");
    }
  }

  private static bool Authorized(User user) => { ... }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文