Comment obtenir un contexte authentifié déjà (de base) pour appeler un service Web après la même authentification?

StackOverflow https://stackoverflow.com/questions/245835

Question

J'ai un site derrière l'authentification de base (IIS6).

Une partie de ce site appelle un service Web qui fait également partie du site et donc derrière l'authentification de base également.

Cependant, lorsque cela se produit, le code de l'appelant reçoit une erreur d'authentification 401.

J'ai essayé plusieurs choses, la recommandation générale étant un code comme celui-ci:

Service.ServiceName s = new Service.ServiceName();
s.PreAuthenticate = true;
s.Credentials = System.Net.CredentialCache.DefaultCredentials;
s.Method("Test");

Cependant, cela ne semble pas résoudre mon problème.

Un conseil?

Modifier

Cela semble être un problème qui n’est pas inhabituel, mais jusqu’à présent, je n’ai trouvé aucune solution. Voici un fil sur le sujet.

Était-ce utile?

La solution

Solution: (je suis presque certain que cela aidera quelqu'un)

Voir ce lien pour connaître le code source de cette solution en VB ( merci jshardy!), tout ce que je faisais était de convertir en C #.

NB: Vous devez utiliser UNIQUEMENT l'authentification de base sur IIS pour que cela fonctionne, mais cette dernière peut probablement être adaptée. Vous devez également passer une instance de page ou au moins la propriété Request.ServerVariables (ou utilisez 'this' si appelé directement depuis une page code-behind). Je ferais ce ménage et supprimerais probablement l'utilisation de références, mais il s'agit d'une traduction fidèle de la solution d'origine et vous pouvez apporter les modifications nécessaires.

public static void ServiceCall(Page p)
{
    LocalServices.ServiceName s = new LocalServices.ServiceName();
    s.PreAuthenticate = true; /* Not sure if required */

    string username = "";
    string password = "";
    string domain = "";
    GetBasicCredentials(p, ref username, ref password, ref domain);

    s.Credentials = new NetworkCredential(username, password, domain);
    s.ServiceMethod();
}


/* Converted from: http://forums.asp.net/t/1172902.aspx */
private static void GetBasicCredentials(Page p, ref string rstrUser, ref string rstrPassword, ref string rstrDomain)
{
    if (p == null)
    {
        return;
    }

    rstrUser = "";
    rstrPassword = "";
    rstrDomain = "";

    rstrUser = p.Request.ServerVariables["AUTH_USER"];
    rstrPassword = p.Request.ServerVariables["AUTH_PASSWORD"];

    SplitDomainUserName(rstrUser, ref rstrDomain, ref rstrUser);

    /* MSDN KB article 835388
       BUG: The Request.ServerVariables("AUTH_PASSWORD") object does not display certain characters from an ASPX page */
    string lstrHeader = p.Request.ServerVariables["HTTP_AUTHORIZATION"];
    if (!string.IsNullOrEmpty(lstrHeader) && lstrHeader.StartsWith("Basic"))
    {
        string lstrTicket = lstrHeader.Substring(6);
        lstrTicket = System.Text.Encoding.Default.GetString(Convert.FromBase64String(lstrTicket));
        rstrPassword = lstrTicket.Substring((lstrTicket.IndexOf(":") + 1));
    }

    /* At least on my XP Pro machine AUTH_USER is not set (probably because we're using Forms authentication 
       But if the password is set (either by AUTH_PASSWORD or HTTP_AUTHORIZATION)
       then we can use LOGON_USER*/
    if (string.IsNullOrEmpty(rstrUser) && !string.IsNullOrEmpty(rstrPassword))
    {
        rstrUser = p.Request.ServerVariables["LOGON_USER"];
        SplitDomainUserName(rstrUser, ref rstrDomain, ref rstrUser);
    }
}

/* Converted from: http://forums.asp.net/t/1172902.aspx */
private static void SplitDomainUserName(string pstrDomainUserName, ref string rstrDomainName, ref string rstrUserName)
{
    rstrDomainName = "";
    rstrUserName = pstrDomainUserName;

    int lnSlashPos = pstrDomainUserName.IndexOf("\\");
    if (lnSlashPos > 0)
    {
        rstrDomainName = pstrDomainUserName.Substring(0, lnSlashPos);
        rstrUserName = pstrDomainUserName.Substring(lnSlashPos + 1);
    }
}

Autres conseils

La ligne:

s.Credentials = System.Net.CredentialCache.DefaultCredentials();

Peut-être devriez-vous essayer:

s.Credentials = HttpContext.Current.User.Identity;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top