Архив

Публикации с меткой ‘c#’

ASP.NET определение локали клиента.

В моем ASP.NET приложении язык интерфейса определяется на основании значения AcceptLanguage в заголовке запроса, отправленного клиентским браузером.

 

Все строковые константы в разметке поддтягиваются из ресурсов.
Для этого в секции system.web в web.config добавлена такая настройка:
<globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true" />

Читать далее…

ICSharpCode.TextEditor: подсветка SQL синтаксиса

Понадобился быстрый и простой в использовании .NET компонент для подсветки синтаксиса в Вашей программе? Тогда вам стоит обратить свое внимание на компонент ICSharpCode.TextEditor от разработчиков open-source проекта #develop. (На момент написания этого поста она распространяется по лицензии LGPL).

По умолчанию ICSharpCode.TextEditor поддерживает подсветку синтаксиса следующих языков: ASP/XHTML, BAT, Boo, Coco, C++.NET, C#, HTML, Java, JavaScript, Patch, PHP, TeX, VBNET, XML. Мы добавим в этот список еще и SQL Читать далее…

Настройка сквозной аутентификации в WCF службе.


Windows Communication Foundation (WCF) — программный каркас, предназначеный для обмена данными между приложениями и входящий в состав .NET Framework, начиная с версии 3.0. До официального релиза третьего фреймворка WCF был известен под кодовым именем Indigo.

WCF дает возможность строить безопасные и отказоустойчивые транзакционные системы через упрощённую унифицированную программную модель межплатформенного взаимодействия. В этой статье мы попробуем разобраться в настройке этой безопасной системы. $CUT$

Моя задача заключалась в следующем:
Необходимо из ASP.NET Web приложения вызывать методы WCF службы в контексте текущего аутентифицированного пользователя. WCF служба хоститься в Windows службе, Web приложение, соответственно, в IIS. Поскольку и web приложение и служба физически располагаются на одном сервере (сервис выступает в роли провайдера данных между приложением и БД Oracle) я использовал привязку basicHttpBinding, хотя в принципе для этих целей можно было выбрать и netTcpBinding. Попробуем разобраться как же передать контекст пользователя службе:

Шифрование соединения может осуществляться в следующих режимах:
  • None  -  SOAP сообщения не шифруются. Является значением по умолчанию.
  • Transport  -  Безопасность обеспечивается использованием HTTPS. В этом случае сервис должен быть сконфигурирован для использования SSL сертификатов.
  • TransportWithMessageCredential  -  этот режим обеспечивает целостность, конфиденциальность, и серверную аутентификацию используя HTTPS. Сервис должен быть сконфигурирован для использования SSL сертификатов. Этот режим применяется в том случае, когда пользователь аутентифицируется с использованием Логина/Пароля или удостоверяющего сертификата и, в если он существует, развертывается канал HTTPS для безопасной передачи сообщений.
  • TransportCredentialOnly  -  этот режим обеспечивает простую HTTP аутентификацию клиента. Он не обеспечивает целостности и конфеденциальности сообщений.
Поскольку для нашей задачи шифровать данные совсем не нужно, нужно лишь передать контекст пользователя службе, выбираем последний вариант <security mode=»TransportCredentialOnly»>.

Далее зададим тип аутентификации клиента на уровне транспорта. Нас интересует аутентификация средствами Windows, поэтому значение атрибута ставим соответствующее: <transport clientCredentialType=»Windows»/> 
В итоге секция привязок должна получится вот такой:

Code
<bindings> 
  <basicHttpBinding>
    <binding name=»BasicHttp»> 
      <security mode=»TransportCredentialOnly»> 
        <transport clientCredentialType=»Windows» /> 
      </security> 
    </binding> 
  </basicHttpBinding>
</bindings>


Теперь добавим описание оконечной точки в секцию <services>:

Code
<services>
  <service name=»System.SubSystem.DataAccess» behaviorConfiguration=»HttpBehavior»>
    <endpoint contract=»System.SubSystem.IDataAccess» 
          binding=»basicHttpBinding» 
          bindingConfiguration=»BasicHttp»/> 
      <host> 
        <baseAddresses> 
          <add baseAddress=»http://localhost:8734/System.SubSystem.DataAccess» /> 
        </baseAddresses> 
      </host> 
  </service>
</services>

И поведение в секцию <behaviors>

Code
<behaviors> 
  <serviceBehaviors>
    <behavior name=»HttpBehavior» > 
      <serviceMetadata httpGetEnabled=»true» /> 
    </behavior> 
  </serviceBehaviors>
<behaviors> 

В базовый класс станиц нашего сайта (у меня это BasePage.cs) добавляем свойство:

Code
private static IDataAccess DataAccess 
  {
     get 
     { 
        BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly); 
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; 
        ChannelFactory<IDataAccess> channelFactory = new ChannelFactory<IDataAccess> 
            ( 
             binding, 
             new EndpointAddress(«http://localhost:8734/System.SubSystem.DataAccess»)); 
        return channelFactory.CreateChannel(); 
     } 
  }

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

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

Вроде бы все просто. Ан нет! Все дело в том что при такой настройке WCF служба для аутентификации получит контекст пользователя, под которым в данный момент запущен AppPool, который хостит наш сайт. Как же получить контекст пользователя, который работает с сайтом. Тут на помощь приходит так называемое «олицетворение». Если включено олицетворение для приложения ASP.NET, это приложение может выполняться в одном из двух различных контекстов: как пользователь, прошедший проверку подлинности в IIS, или как произвольная, заданная пользователем учетная запись. По умолчанию олицетворение ASP.NET отключено. Включить его можно добавив атрибут impersonate в секцию <identity/> конфигурационного файла сайта web.config

Code
<configuration>
  <system.web>
    <identity impersonate=»true» /> 
  </system.web>
 </configuration>