2010-01-13 11 views
7

Z powodzeniem wdrożyłem autoryzację opartą na rolach w ASP.NET. Kiedy dana osoba nie ma potrzebnej roli, dostrzega stronę błędu dla 401.2, która nie jest autoryzowana.customerrors dla 401.2 w ASP.NET

To, co chciałbym teraz osiągnąć to mieć niestandardową stronę 401 w mojej aplikacji i przekierować tam za pośrednictwem ustawień w pliku web.config. Próbowałem tego:

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> 
    <error statusCode="401" redirect="NoAccess.htm" /> 
</customErrors> 

Ale to się nie przyłapie. Czy zamiast tego muszę zastąpić go w IIS? Mam nadzieję, że nie, ponieważ to sprawiłoby, że rzeczy byłyby bardziej rozmieszczone.

Odpowiedz

7

Ostatnio napotkałem ten sam problem i okazało się, że jest to jedno z dziwactw podczas korzystania z uwierzytelniania systemu Windows.

Joshua Flanagan stworzył przed chwilą nice HttpModule, który będzie respektował sekcję customErrors w twoim web.config i przekierowuje na stronę błędu 401.

Kluczem do rozwiązania jest to, aby przechwycić zdarzenie EndRequest cyklu życia strony, należy sprawdzić kod statusu 401, a następnie wykonać swoją stronę niestandardową.

przenośności HttpModule jest dobre, bo to sprawia, że ​​rozwiązanie wielokrotnego użytku, i utrzymuje Global.asax czyste, ale nie ma nic Cię powstrzymuje od okablowania swój EndRequest zdarzenie w Global.asax z jego kod Jeśli naprawdę chciał.

Jeśli używasz ASP.NET MVC, rozwiązanie nie jest tak eleganckie.

3

Jeśli nie chcesz, aby dodać HttpModule

w web.config

<system.web> 
    <customErrors mode="On" defaultRedirect="~/MyController/MyErrorAction/" redirectMode="ResponseRedirect"> 
     <error statusCode="401" redirect="~/MyController/MyErrorAction/" /> 
    </customErrors> 

w Global.asax.cs

protected void Application_EndRequest(object sender, EventArgs e) 
    { 
     HttpApplication application = (HttpApplication)sender; 

     if (application.Response.StatusCode != 401 || !application.Request.IsAuthenticated) return; 

     application.Response.ClearContent(); 

     //You can replace the piece below is to redirect using MVC, or your can replace all this with application.Server.Execute(yourPage); 
     IController errorController = new SharedController(); 
     var rd = new RouteData(); 
     rd.Values.Add("controller", "MyController"); 
     rd.Values.Add("action", "MyErrorAction"); 
     rd.Values.Add("value", "You or your user group do not have permissions to use the address: " + Request.Url.PathAndQuery); 

     errorController.Execute(new RequestContext(new HttpContextWrapper(Context), rd)); 
     HttpContext.Current.Server.ClearError(); 
    } 
+0

Czy negacja Is IsAirified naprawdę jest prawidłowa? Czy nie powinno być odwrotnie, tzn. Czy uwierzytelniony => powrót z metody? – aeliusd

3

Oto MVC agnostyk wariant:

In Web.config

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> 
    <error statusCode="401" redirect="NoAccess.htm" /> 
</customErrors> 

W Global.asax.cs

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    HttpApplication application = (HttpApplication)sender; 

    if (application.Response.StatusCode != 401 || !application.Request.IsAuthenticated) return; 

    var customErrors = (CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors"); 

    var accessDeniedPath = customErrors.Errors["401"] != null ? customErrors.Errors["401"].Redirect : customErrors.DefaultRedirect; 
    if (string.IsNullOrEmpty(accessDeniedPath)) 
     return; // Let other code handle it (probably IIS). 

    application.Response.ClearContent(); 
    application.Server.Execute(accessDeniedPath); 
    HttpContext.Current.Server.ClearError(); 
} 
2

Oto, co działa dobrze dla mnie.

Global.asax -

protected void Application_EndRequest(object sender, EventArgs e) 
    { 
     if (Response.StatusCode == 401 && Request.IsAuthenticated) 
     { 
      Response.StatusCode = 303; 
      Response.Clear(); 
      Response.Redirect("~/AccessDenied.html"); 
      Response.End(); 
     } 
    } 

Web.config -

<system.web> 
    <customErrors mode="On"> 
     <error statusCode="401" redirect="AccessDenied.html"/> 
    </customErrors> 
    <authentication mode="Windows"/> 
    </system.web> 
    <location path="AccessDenied.html"> 
    <system.web> 
     <authorization> 
     <allow roles="*"/> 
     </authorization> 
    </system.web> 
    </location> 
    <location path="."> 
    <system.web> 
     <authorization> 
     <allow roles="YourADGroup"/> 
     <deny users="*" /> 
     </authorization> 
    </system.web> 
    </location> 

ta dba o podwójnym 401 przed 200 emisji, jak również. Pomija także okno dialogowe uwierzytelniania firefox.