Как получить уже (базовый) аутентифицированный контекст для вызова веб-службы за той же аутентификацией? - PullRequest
3 голосов
/ 29 октября 2008

У меня есть сайт за базовой аутентификацией (IIS6).

Часть этого сайта называется веб-службой, которая также является частью сайта и, следовательно, за базовой аутентификацией.

Однако, когда это происходит, вызывающий код получает ошибку аутентификации 401.

Я попробовал пару вещей, с общей рекомендацией, такой как код:

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

Однако, похоже, это не решает мою проблему.

Любой совет?

Редактировать

Кажется, это не редкая проблема, но до сих пор я не нашел решений. Вот одна тема по теме.

Ответы [ 2 ]

3 голосов
/ 30 октября 2008

Решение: (Я почти уверен, что это кому-то поможет)

См. эту ссылку , чтобы узнать источник этого решения в VB (спасибо, jshardy!), Все, что я сделал, это конвертировал в C #.

NB: Вы должны использовать ТОЛЬКО базовую аутентификацию на IIS, чтобы это работало, но, вероятно, ее можно адаптировать. Вам также необходимо передать экземпляр страницы в или, по крайней мере, свойство Request.ServerVariables (или использовать 'this', если он вызывается непосредственно из кода страницы). Я бы убрал это и, вероятно, исключил бы использование ссылок, но это точный перевод оригинального решения, и вы можете внести любые необходимые изменения.

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);
    }
}
0 голосов
/ 29 октября 2008

Линия:

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

Может быть, вам стоит попробовать:

s.Credentials = HttpContext.Current.User.Identity;
...