C # Проблема аутентификации веб-службы между двумя веб-приложениями - PullRequest
3 голосов
/ 28 сентября 2010

Я работаю над веб-приложением, которое работает централизованно в компании. Это веб-приложение должно вызвать службу, которая является частью второго веб-приложения.

В центральном веб-приложении у меня есть этот кусок кода;

var clientUri = "http://website.localhost/Services/Info.svc/account";
var uri = new Uri(clientUri);
var networkCredentials = new NetworkCredential(_configuration.ServiceUserName, _configuration.ServicePassword);
var httpClient = new HttpClient();

httpClient.DefaultHeaders.Authorization = Credential.CreateBasic(_configuration.ServiceUserName,                                                                                   _configuration.ServicePassword);
httpClient.TransportSettings.PreAuthenticate = true;

HttpResponseMessage respone = httpClient.Get(uri);
HttpContent content = respone.Content;

В веб-сервисе в другом приложении (Info.svc) у меня есть следующий код в конструкторе службы.

var validator = new UserNamePasswordValidator();
var cred = System.Net.CredentialCache.DefaultCredentials; //this one is empty, maybe a solution?
validator.Validate("Username", "Password");

if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
//This throws a 401 unauthorize, which is shown as a 500 error in the central application
throw new WebProtocolException(HttpStatusCode.Unauthorized, "You must be authorized to perform this action.", null);
}
else
{
_userIsAbleToUseService = true;
}

Вместо имени пользователя и пароля в функции проверки я хочу использовать сетевые учетные данные, отправленные с другого веб-сервиса, можно ли этого достичь? И как? Любые другие предложения приветствуются! Теперь я могу записать пароль в функции проверки, но это не то, что я хочу.

- UPDATE-- Это конфигурация в web.config для центрального приложения

<authorization>
            <allow roles="administrators"/>
            <deny roles="datareaders"/>
            <deny users="?"/>
        </authorization>

<authentication mode="Forms">
            <forms loginUrl="~/Logon/Logon" timeout="2880"/>
        </authentication>
        <membership>
            <providers>
                <clear/>
                <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="CentralApplication"/>
            </providers>
        </membership>

Эта часть предназначена для web.config во втором веб-приложении

<authentication mode="Forms">
      <forms name="AllPages" loginUrl="~/Logon/" timeout="360" enableCrossAppRedirects="false" />
    </authentication>
    <authorization>
      <!-- NOTE: See Web.config under Private folder for specifics on secure pages. -->
      <deny users="?" />
    </authorization>

<membership defaultProvider="NHMembershipProvider">
      <providers>
        <clear />
        <add name="NHMembershipProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsMembershipProvider" description="Stores and retrieves membership data from SQL server using Nhibernate" connectionStringName="NHibernate" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="NHRoleProvider">
      <providers>
        <clear />
        <add name="NHRoleProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsRoleProvider" />
      </providers>
    </roleManager>

Уже входя в центральное приложение, используя поставщика членства, я пытаюсь вызвать оттуда веб-службу, используя простую гиперссылку (только сейчас). Веб-служба, вызываемая центральным администратором, собирает некоторые данные и отправляет их на URL-адрес веб-службы второго приложения. Оба приложения являются веб-приложениями (содержащими веб-сервисы), поэтому режим аутентификации установлен на Forms.

1 Ответ

0 голосов
/ 01 октября 2010

У меня ушло почти 2 дня, но теперь у меня все работает так, как я хочу. Я обнаружил WcfRestContrib , который позволил мне реализовать аутентификацию на сервисах, немного изменив мою веб-конфигурацию и используя несколько атрибутов из этого класса. Я создаю быстрое приложение для тестирования со службой и консольным приложением, и аутентификация работает.

Я добавил раздел ниже в свой web.config;

<system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="webAuthentication" type="WcfRestContrib.ServiceModel.Configuration.WebAuthentication.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
        <add name="errorHandler" type="WcfRestContrib.ServiceModel.Configuration.ErrorHandler.BehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
        <add name="webErrorHandler" type="WcfRestContrib.ServiceModel.Configuration.WebErrorHandler.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Rest">
          <webAuthentication requireSecureTransport="false" authenticationHandlerType="WcfRestContrib.ServiceModel.Dispatcher.WebBasicAuthenticationHandler, WcfRestContrib" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, CMS.Backend" source="CMS.Backend"/>
          <!--<webAuthentication requireSecureTransport="false" authenticationHandlerType="CMS.Backend.Services.WebBasicAuthenticationHandler, CMS.Backend" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, Website.Backend" source="CMS.Backend"/>-->
          <errorHandler errorHandlerType="WcfRestContrib.ServiceModel.Web.WebErrorHandler, WcfRestContrib"/>
          <webErrorHandler returnRawException="true" logHandlerType="Website.Backend.Services.LogHandler, Website.Backend" unhandledErrorMessage="An error has occured processing your request. Please contact technical support for further assistance."/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

После этого я изменил свой сервисный интерфейс, чтобы он выглядел следующим образом;

[ServiceContract]
public interface ICmsInfo
{
    [OperationContract]
    [OperationAuthentication]
    [WebInvoke(UriTemplate = "account", Method = "GET")]
    AccountDTO GetAccountInfo();

Последний шаг, который я предпринял, - это добавление двух атрибутов к самой службе;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceConfiguration("Rest", true)]
public class Cmsinfo : ICmsInfo
{
//foo
}

WcfRestContrib мне очень помог, добавив эту технику аутентификации, и она прекрасно работает. Мне просто нужно убедиться, что я использовал заголовки авторизации.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...