none
Cambiar 401 UNAUTHORIZED al logarse RRS feed

  • Pregunta

  • Hola a todos,

    tengo un portal de Moss con acceso anónimo, cuando pincho en "Iniciar sesión" se habre la ventana para autentificarse, el problema es que si pulsamos cancelar me aparece el horrendo mensaje de "401 UNAUTHORIZED", yo lo que necesitaría sería que en vez de esto me redireccionara de nuevo a la página continuando con el acceso anónimo. ¿Como puedo hacerlo?

    Me corre muchisima prisa, por ello agradeceré cualquier tipo de consejo, pista, intuición.....

    Muchas gracias por vuestro tiempo.

    Un saludo.

    viernes, 24 de abril de 2009 13:23

Respuestas

  • <%@ Page language="C#"     %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages" %> 
    <script runat="server">
    
    public void MyEnsureAuthentication()
    {
    //tu tenias SPWeb web = SPWeb spWeb =SPControl.GetContextWeb(Context); y me daba un error
        SPWeb web =  SPControl.GetContextWeb(Context); 
        MyEnsureAuthentication(web);
    }
    
     
    public void MyEnsureAuthentication(SPWeb web)
    {
        if ((web == null) || (HttpContext.Current == null) || !HttpContext.Current.User.Identity.IsAuthenticated)
        {
    //tu tenias MySendaccessDeniedHeader supongo que una herrata jejeje
            SendAccessDeniedHeader(new UnauthorizedAccessException());
        }
    }
    
    //en este metodo tu lo tenias declarado como estatico y no reconocía context si quetas el atributo static aparece aquí seguramente venga mi problema
    public void SendAccessDeniedHeader(Exception ex)
    {
        HttpContext current = HttpContext.Current;
        if (current == null)
        {
            throw ex;
        }
        SPUtility.Redirect("Tu_Url_Con_MensajeDeError", SPRedirectFlags.UseSource, Context);
    }
    
    
    
    </script>
    
    <% 
    
    SPSite spServer = SPControl.GetContextSite(Context); 
    SPWeb spWeb = SPControl.GetContextWeb(Context); 
    
    MyEnsureAuthentication();
    
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    
    %>
    Hola Mario,

    gracias por tu respuesta, por ahora mis esfuerzos habian sido tocando el Authenticate.aspx pero sin ningún resultado. H estado probando con el codigo que me has facilitado y tras una serie de modificaciones he conseguido que funcione. Sin embargo el problema es que ahora no me sale la ventana para logarse, te pongo el codigo exxplicandote los cambios que he tenido que realizar haber si a ti se te acurre algo.

    Muchisimas gracias por tu tiempo, me es muy muy urgente por lo cual te puedo decir que me estas salvando la vida.

    Gracias de nuevo

    • Marcado como respuesta Merillas lunes, 27 de abril de 2009 14:53
    lunes, 27 de abril de 2009 10:18

Todas las respuestas

  • Hola, cuando desde sharepoint se produce el error "401 UNAUTHORIZED" lo que hace es llevarte a la pplicationpage "_layouts/AccessDenied.aspx", esta página puedes encontrarla en el directorio "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS" o "C:\Archivos de programa\Archivos comunes\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS".

    Si quieres editarla te aconsejo que hagas una copia primero, y luego la modifiques como una nueva ApplicationPage, no intentes editar el contenido de la página aspx porque hereda de Microsoft.SharePoint.ApplicationPages.AccessDeniedPage y siempre te va a devolver el mismo resultado.

    Un ejemplo sería:

    <%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
    <%@ Page Language="C#" MasterPageFile="~/_layouts/application.master"
             Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase" %>
    
    <%@ Import Namespace="Microsoft.SharePoint" %>
    
    <script runat="server">
      protected override void OnLoad(EventArgs e) {
        // Mete tu código
          SPWeb site = this.Web;
          lkbVolverAlSitio.PostBackUrl = site.Url;
      }
    </script>
    
    <asp:Content ID="Main" contentplaceholderid="PlaceHolderMain" runat="server">
      <asp:LinkButton runat="server" ID="lkbVolverAlSitio" Text="Volver al sitio" ></asp:LinkButton>
    </asp:Content>
    
    <asp:Content ID="PageTitle" runat="server"
                 contentplaceholderid="PlaceHolderPageTitle" >
      Acceso denegado
    </asp:Content>
    <asp:Content ID="PageTitleInTitleArea" runat="server"
                 contentplaceholderid="PlaceHolderPageTitleInTitleArea" >
      Acceso denegado, verifique la cuenta de usuario y contraseña.
    </asp:Content>
    




    http://geeks.ms/blogs/mcortes/ http://mariocortesflores.blogspot.com/
    viernes, 24 de abril de 2009 17:42
  • Hola Mario,

    en primer lugar darte las gracias por tu respuesta.
    Una pregunta el codigo de ejemplo que pasas donde lo tendría que meter, dices que no intente modificar la de AccessDenied.aspx y que intente modificarla como application page, como hago eso? lo siento si te parece muy obvio pero nunca tuve que hacer nada parecido.
    Una cosa, a lo mejor un poco absurda cuando me dá el mensaje de "401 ..." la url pone authentification.aspx que le pasa por query string source=url de la pagina donde intenté logarme.


    Gracias de nuevo.

    lunes, 27 de abril de 2009 8:11
  • aaa, ok, esque estaba mirando la página de cambio de usuario que también da el mismo mensaje.

    La página "authentification.aspx" en realidad imagino que te refieres a "Authenticate.aspx", esta página también está en el mismo directorio que la anterior. Si la editas verás que hay un código del tipo:
    <%
    SPUtility.EnsureAuthentication();
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    %>

    Haciendo un poco de reflector de Microsoft.Sharepoint.dll verás que el método SPUtility.EnsureAuthentication() al final llama al método SPUtilityInternal.Send401 que lo que hace es escribir directamente el texto "401 UNAUTHORIZED" en el stream de salida de la página aspx.

    Para personalizar el método EnsureAuthentication puedes editar esta página y hacer algo parecido a esto:

    <%@ Page language="C#"     %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages" %> 
    <script runat="server">
    
    public void MyEnsureAuthentication()
    {
        SPWeb web = SPWeb spWeb = SPControl.GetContextWeb(Context); 
        MyEnsureAuthentication(web);
    }
    
     
    public void MyEnsureAuthentication(SPWeb web)
    {
        if ((web == null) || (HttpContext.Current == null) || !HttpContext.Current.User.Identity.IsAuthenticated)
        {
            MySendAccessDeniedHeader(new UnauthorizedAccessException());
        }
    }
    
    public static void SendAccessDeniedHeader(Exception ex)
    {
        HttpContext current = HttpContext.Current;
        if (current == null)
        {
            throw ex;
        }
        SPUtility.Redirect("Tu_Url_Con_MensajeDeError", SPRedirectFlags.UseSource, Context);
    }
    
    
    
    </script>
    
    <% 
    
    SPSite spServer = SPControl.GetContextSite(Context); 
    SPWeb spWeb = SPControl.GetContextWeb(Context); 
    
    MyEnsureAuthentication();
    
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    
    %>



    Otra solución es configurar validación en modo formulario, igual te resulta más fácil, aunque lo recomendable suele ser NTLM.


    http://geeks.ms/blogs/mcortes/ http://mariocortesflores.blogspot.com/
    lunes, 27 de abril de 2009 9:20
  • <%@ Page language="C#"     %>
    <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages" %> 
    <script runat="server">
    
    public void MyEnsureAuthentication()
    {
    //tu tenias SPWeb web = SPWeb spWeb =SPControl.GetContextWeb(Context); y me daba un error
        SPWeb web =  SPControl.GetContextWeb(Context); 
        MyEnsureAuthentication(web);
    }
    
     
    public void MyEnsureAuthentication(SPWeb web)
    {
        if ((web == null) || (HttpContext.Current == null) || !HttpContext.Current.User.Identity.IsAuthenticated)
        {
    //tu tenias MySendaccessDeniedHeader supongo que una herrata jejeje
            SendAccessDeniedHeader(new UnauthorizedAccessException());
        }
    }
    
    //en este metodo tu lo tenias declarado como estatico y no reconocía context si quetas el atributo static aparece aquí seguramente venga mi problema
    public void SendAccessDeniedHeader(Exception ex)
    {
        HttpContext current = HttpContext.Current;
        if (current == null)
        {
            throw ex;
        }
        SPUtility.Redirect("Tu_Url_Con_MensajeDeError", SPRedirectFlags.UseSource, Context);
    }
    
    
    
    </script>
    
    <% 
    
    SPSite spServer = SPControl.GetContextSite(Context); 
    SPWeb spWeb = SPControl.GetContextWeb(Context); 
    
    MyEnsureAuthentication();
    
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    
    %>
    Hola Mario,

    gracias por tu respuesta, por ahora mis esfuerzos habian sido tocando el Authenticate.aspx pero sin ningún resultado. H estado probando con el codigo que me has facilitado y tras una serie de modificaciones he conseguido que funcione. Sin embargo el problema es que ahora no me sale la ventana para logarse, te pongo el codigo exxplicandote los cambios que he tenido que realizar haber si a ti se te acurre algo.

    Muchisimas gracias por tu tiempo, me es muy muy urgente por lo cual te puedo decir que me estas salvando la vida.

    Gracias de nuevo

    • Marcado como respuesta Merillas lunes, 27 de abril de 2009 14:53
    lunes, 27 de abril de 2009 10:18
  • Hola tienes razón, no funciona bien. He estado hechando un vistazo pero no consigo que funcione como necesitas.

    Lo único que se me ocurre es utilizar autenticación por formulario y modificar la página login.aspx. Esta página tiene un control del tipo asp:login puedes probar a capturar el evento LoginError para que actúe como comentabas.



    http://geeks.ms/blogs/mcortes/ http://mariocortesflores.blogspot.com/
    lunes, 27 de abril de 2009 14:41
  • Hola,

    tras mucho cacharrear he conseguido al fin una solución, para dejar un codigo que funciona (para lo que yo quiero al menos) os dejo el codigo usado. Lo que hace es en caso de que el usuario cancele la acción de loguearse te redirecciona a la pagina en la que te encontrabas.
    Pd: Muchisimas gracias Mario sin tu ayuda estaría dandome de cabezazos contra el ordenador todavia, la idea del reflector en la dll de sharepoint me ha abierto nuevos horizontes jejeje

    <%@ Page language="C#"     %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>  <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages" %> <% SPSite spServer = SPControl.GetContextSite(Context); SPWeb spWeb = SPControl.GetContextWeb(Context); %>
    
    <script runat="server">
        
    public void MyEnsureAuthentication()
    {
        SPWeb web = null;
    
        if (HttpContext.Current != null)
        {
            web = (SPWeb)HttpContext.Current.Items["HttpHandlerSPWeb"];
        }
        MyEnsureAuthentication(web);
    
    
    }
    
     
    public void MyEnsureAuthentication(SPWeb web)
    {
        if ((web == null) || !HttpContext.Current.User.Identity.IsAuthenticated)
        {
            MySendAccessDeniedHeader(new UnauthorizedAccessException());
        }
    }
    
    public void MySendAccessDeniedHeader(Exception ex)
    {
        HttpContext current = HttpContext.Current;
        if (current == null)
        {
            throw ex;
        }
        Send401(current.Response);
    
        //SPUtility.Redirect("Tu_Url_Con_MensajeDeError", SPRedirectFlags.UseSource, Context);
    }
        internal  void Send401(HttpResponse response)
        {
            //SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
            SendResponse(response, 0x191, "ESte no es el mismo error");
           
            
        }
        internal void SendResponse(HttpResponse response, int code, string strBody)
        {
            SPWeb web = SPControl.GetContextWeb(Context);
            string text = "<head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=" + web.Url.ToString() +"\"></head>";
            HttpContext current = HttpContext.Current;
            object obj2 = current.Items["ResponseEnded"];
            
            if ((obj2 == null) || !((bool)obj2))
            {
               
                current.Items["ResponseEnded"] = true;
                response.StatusCode = code;
                response.Clear();
                if (strBody != null)
                {
                    
                    response.Write(text);
                    
                }
               
                response.End();
               
            }
        }
       
    
     
    
    
    
    
    </script>
    
    <% 
    
    //SPSite spServer = SPControl.GetContextSite(Context); 
    //SPWeb spWeb = SPControl.GetContextWeb(Context); 
    
    MyEnsureAuthentication();
    
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    
    %>
    
    Un saludo y espero que os ayude a alguno en el futuro!!!!
    
    
    Daniel Merillas
    http://www.weblogfree.com/weblog/internet/merix/default.aspx
    martes, 28 de abril de 2009 7:49
  • Hola,

    tras mucho cacharrear he conseguido al fin una solución, para dejar un codigo que funciona (para lo que yo quiero al menos) os dejo el codigo usado. Lo que hace es en caso de que el usuario cancele la acción de loguearse te redirecciona a la pagina en la que te encontrabas.
    Pd: Muchisimas gracias Mario sin tu ayuda estaría dandome de cabezazos contra el ordenador todavia, la idea del reflector en la dll de sharepoint me ha abierto nuevos horizontes jejeje

    <%@ Page language="C#"     %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>  <%@ Assembly Name="Microsoft.SharePoint.ApplicationPages" %> <% SPSite spServer = SPControl.GetContextSite(Context); SPWeb spWeb = SPControl.GetContextWeb(Context); %>
    
    <script runat="server">
        
    public void MyEnsureAuthentication()
    {
        SPWeb web = null;
    
        if (HttpContext.Current != null)
        {
            web = (SPWeb)HttpContext.Current.Items["HttpHandlerSPWeb"];
        }
        MyEnsureAuthentication(web);
    
    
    }
    
     
    public void MyEnsureAuthentication(SPWeb web)
    {
        if ((web == null) || !HttpContext.Current.User.Identity.IsAuthenticated)
        {
            MySendAccessDeniedHeader(new UnauthorizedAccessException());
        }
    }
    
    public void MySendAccessDeniedHeader(Exception ex)
    {
        HttpContext current = HttpContext.Current;
        if (current == null)
        {
            throw ex;
        }
        Send401(current.Response);
    
        //SPUtility.Redirect("Tu_Url_Con_MensajeDeError", SPRedirectFlags.UseSource, Context);
    }
        internal  void Send401(HttpResponse response)
        {
            //SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
            SendResponse(response, 0x191, "ESte no es el mismo error");
           
            
        }
        internal void SendResponse(HttpResponse response, int code, string strBody)
        {
            SPWeb web = SPControl.GetContextWeb(Context);
            string text = "<head><meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=" + web.Url.ToString() +"\"></head>";
            HttpContext current = HttpContext.Current;
            object obj2 = current.Items["ResponseEnded"];
            
            if ((obj2 == null) || !((bool)obj2))
            {
               
                current.Items["ResponseEnded"] = true;
                response.StatusCode = code;
                response.Clear();
                if (strBody != null)
                {
                    
                    response.Write(text);
                    
                }
               
                response.End();
               
            }
        }
       
    
     
    
    
    
    
    </script>
    
    <% 
    
    //SPSite spServer = SPControl.GetContextSite(Context); 
    //SPWeb spWeb = SPControl.GetContextWeb(Context); 
    
    MyEnsureAuthentication();
    
    SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context);
    
    %>
    
    Un saludo y espero que os ayude a alguno en el futuro!!!!
    
    
    Daniel Merillas
    http://www.weblogfree.com/weblog/internet/merix/default.aspx
    martes, 28 de abril de 2009 7:50