Programación y Estrategias de Negocios RSS 2.0
# Wednesday, August 20, 2008

Me han preguntado un par de veces como invocar Web Services que tienen certificados digitales desde aplicaciones web (y tambien desde aplicaciones Windows), asi que aqui una nota de referencia rapida y algunos enlaces al respecto:

 

Existen muchas formas de invocar servicios web seguros desde aplicaciones web, pero basicamente dos son rapidas y eficaces y dependen de la tecnología que se este usando para invocar los servicios web. (es decir como los esta llamando), si esta usando framework 2.0 lo mejor es usar Web Services Enhancements (WSE) 3.0 for Microsoft .NET, una serie de extensiones para Visual Studio que implementan mejoras significativas en seguridad, gestión de archivos como parte del mensaje, etc. Con WSE* puede usar muchas de las características más avanzadas de Web Services y hacen parte de los estándares avalados por OASIS y otras sugerencias de Microsoft, incluidos los certificados digitales, mas información de esta técnica aquí. Este complemento es gratuito, no hay que pagar nada por él y se puede descargar del sitio de Microsoft haciendo clic aquí.

 

Ahora si está usando el framework 3.0 puede utilizar Windows Communication Foundation (WCF) que trae incluido desde el core el soporte para esquemas de seguridad como el que menciona, Microsoft ha desarrollado una guía de mejores prácticas de seguridad para servicios de WCF. Y una guía muy completa de casos practicos (how-to) y escenarios que se puede descargar de forma gratuita haciendo clic aquí.

 

 

Juan Peláez

Developer Evangelist

Microsoft Colombia.

Wednesday, August 20, 2008 8:33:57 AM (SA Pacific Standard Time, UTC-05:00)  #    Comments [0] - Trackback
.net | Articulos de Desarrollo | Developer Evangelist | Visual Studio | WCF | Web Services
# Tuesday, March 04, 2008

Este post tiene que ver con la forma como se invocan servicios Web usando certificados X.509.  En especial visto como una guía muy básica de resolución de problemas al momento de configurar los clientes.  (Que como ya debe saberse pueden ser aplicaciones de escritorio o Aplicaciones Web).

 

Antecedentes.

La seguridad es un elemento clave en la construcción de servicios web, especialmente cuando estos servicios web se exponen en internet.

Para poder construir servicios web seguros se pueden utilizar diversos métodos de autenticación y certificación de identidad, algunos de ellos incluyen:

 

· Tokens de Seguridad Personalizados

· Tokens de Seguridad del Contexto

· Tiquetes de Kerberos

· Usuario y Contraseña

· y Certificados X.509, que son los que nos interesan hoy.

 

Un certificado X.509 es básicamente una llave de encripción emitida y certificada por una entidad certificadora valida, sin entrar mucho en definiciones que se pueden encontrar mas en detalle en Internet, el certificado es un archivo que me emite una entidad reconocida, y que básicamente es un numero único que me han dado para yo entregar a mis clientes y saber que son ellos los que esta llamando mi servicio.

 

Escenario.

Un cliente me pide invocar un servicio web seguro desde mi propia aplicación web, (por ejemplo para mostrar los valores de un combobox), este cliente me provee un certificado X.509 y me informa la política de encripción, autenticación para este servicio. 

 

Solución.

1. Debo instalar el certificado Digital en la Maquina de desarrollo, en el ambiente de pruebas y en el servidor de Producción, es posible que el cliente me provea con dos direcciones web, una para prueba, otra para desarrollo, eso es independiente del certificado.

2. La instalación del certificado puede realizarse de diversas maneras, una muy fácil es copiar el certificado en una ruta de la maquina donde desea instalarse, luego hacer clic derecho del mouse e seguir el asistente

 

clip_image001

 

La siguiente pregunta del asistente es si desea ubicar el certificado en un almacén determinado o si desea que el asistente lo instale basado en la información del certificado, esta es una de esas típicas preguntas que no se sabe bien que contestar o que significa. El repositorio de certificados esta divido por niveles.

El primer nivel indica si se quiere almacenar el certificado en la maquina local, en el perfil del usuario o en la cuenta del servicio con la que corre el OS.

 

luego viene un segundo nivel que incluye personal, autoridades, entidades certificadoras, directorio activo, entre varias otras, así que lo primero es saber donde colocar el certificado, una buena guía es esta que muestra las ubicaciones por default que se utilizan para buscar los certificados digitales, así, si la aplicación es un web service o una aplicación de escritorio que intenta firmar o encriptar el mensaje va a buscar en el User Personal Store.

 

clip_image002

 

3. Ahora que tengo el servidor instalado debo configurar el webconfig y la política que quiero seguir para este certificado. (hay muchas formas de hacerlo, algunos no usan el web config, sino que crean la política en ejecución, etc. esta es solo una forma de abordar el problema).  En e web config va algo como esto:

 

<!-- WSE 2.0 -->
    <section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

En la parte de configuración - </configSections> (ojo, esto en  VS2003, en VS2005 puede variar)

y claro, la sección donde en realidad hago la configuración (en web config)

<microsoft.web.services2>
    <diagnostics>
      <detailedErrors enabled="true" />
      <trace enabled="true" />
      <policyTrace enabled="true"
       input="receivePolicy.webinfo"
       output="sendPolicy.webinfo"/>
    </diagnostics>
    <tokenIssuer>
      <autoIssueSecurityContextToken enabled="true" />
    </tokenIssuer>
    <policy>
      <cache name="policyCache.config" />
    </policy>
    <security>
      <x509 storeLocation="LocalMachine" verifyTrust="false" allowTestRoot="false" allowRevocationUrlRetrieval="true" allowUrlRetrieval="false" />
    </security>
  </microsoft.web.services2>

 

esta es la versión de desarrollo o de pruebas, como puede ver esta habilitado el trace de la política <policyTrace enabled="true"... y se esta generando archivos con información de las peticiones y las respuestas (input="receivePolicy.webinfo" output="sendPolicy.webinfo"). Para que estos archivos se puedan crear, son súper útiles, debe habilitarse la cuenta con la que esta corriendo la aplicación (ASP.NET generalmente) para que escriba en el directorio donde se esta ejecutando.

 

Lo otro importante de este segmento es el nombre de la política, en este caso policyCache.config. lo que se esta diciendo aquí es que en ese archivo config estará la definición completa de la política, pueden haber tantas políticas como se quiera. y claro, la seguridad usando X.509 y diciendo en que almacén esta el certificado (storeLocation),

 

Ahora el archivo de la política es como esto:

 

<?xml version="1.0" encoding="utf-8"?>
<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
  <mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
    <!--The following policy describes the policy requirements for the service: http://algo.asmx .-->
    <endpoint uri="algo.asmx">
      <defaultOperation>
        <request policy="" />
        <response policy="" />
        <fault policy="" />
      </defaultOperation>
    </endpoint>
    <endpoint uri=http://algo.asmx>
      <defaultOperation>
        <request policy="#Encrypt-X.509" />
        <response policy="" />
        <fault policy="" />
      </defaultOperation>
    </endpoint>
    <endpoint uri=http://algo.asmx>
      <defaultOperation>
        <request policy="#Encrypt-X.509" />
        <fault policy="" />
      </defaultOperation>
    </endpoint>
  </mappings>
  <policies xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wssp="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
    <wsp:Policy wsu:Id="Encrypt-X.509">
        <!--The Confidentiality assertion is used to ensure that the SOAP Body is encrypted.-->
        <wssp:Confidentiality wsp:Usage="wsp:Required">
            <wssp:KeyInfo>
                <!--The SecurityToken element within the KeyInfo element describes which token type must be used for Encryption.-->
          <wssp:SecurityToken>
            <wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
            <wssp:TokenIssuer>C=US, O="VeriSign, Inc.", OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)05, CN=VeriSign Class 3 Secure Server CA</wssp:TokenIssuer>
            <wssp:Claims>
              <!--By specifying the SubjectName claim, the policy system can look for a certificate with this subject name in the certificate store indicated in the application's configuration, such as LocalMachine or CurrentUser. The WSE X.509 Certificate Tool is useful for finding the correct values for this field.-->             <wssp:SubjectName MatchType="wssp:Exact">C=US, S=Wisconsin, L=Milwaukee, O=CLIENTE Company, OU=IS Technical Services, CN=www.cliente.com</wssp:SubjectName>
              <wssp:X509Extension OID="2.7.34.87" MatchType="wssp:Exact">0GJdsds3UdP3fsdtretterERFE4=</wssp:X509Extension>
            </wssp:Claims>
          </wssp:SecurityToken>
            </wssp:KeyInfo>
            <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>
        </wssp:Confidentiality>
    </wsp:Policy>
  </policies>
</policyDocument>

 

Donde he puesto en negrilla los valores que son claves, vienen del certificado y se pueden ubicar usando alguna de las herramientas enumeradas mas adelante.

 

Ya podía verse desde aquí la introducción a los conceptos como endpoint que luego serian aun mas completos en WCF pero eso es otra historia.

 

Herramientas.

Utilidad para ver información de los certificados (con código fuente)

Configurar una consola para gestionar los certificados digitales.

La herramienta de gestión de información de los certificados incluida con WSE*

Referencia

Como Firmar un Mensage usando un certificado X.509

 

Espero que esto le ahorre un par de horas, en resumen, el certificado se instala en una de las ubicaciones de búsqueda por defecto o toca cambiar la configuración en los archivos de config.  Luego se modifica el archivo webconfig y los archivos de políticas con la información que se saca del certificado usando una de las herramientas enumeradas, para poder revisar errores, se habilitan los servicios de trace.

 

Juan Peláez

Arquitecto de Software

 

keywords:  Web Services, WSE, certificados X.509, encriptar, firmar, servicios web, herramientas para configurar certificados digitales, políticas de configuración, certificados digitales. seguridad en servicios web, servicios seguros, identificación de clientes, identidad de clientes.

Tuesday, March 04, 2008 8:10:17 PM (SA Pacific Standard Time, UTC-05:00)  #    Comments [0] - Trackback
Visual Studio | VS2005 | Web Services
# Tuesday, October 02, 2007

Hace algunas semanas Miguel Mendoza me encargo un proyecto para autenticar usuarios contra los servicios de Windows Live (ID) y reenviarlos a la página principal de Windows Live donde podrían contar con los servicios de la plataforma  de Servicios de Microsoft.

Como esta es una aplicación web y después de revisar el tema, la mejor alternativa fue utilizar el SDK for Windows Live ID para autenticación Web, que se descargar desde aquí., sin embargo al momento de instalarlo tuvimos muchos problemas, cada vez que tratábamos de ejecutar obteníamos problemas de permisos que impedían la instalación. Reiniciamos con varios roles, promovimos los usuarios, etc, pero nada servía. Luego de una búsqueda por internet encontramos la solución que público aquí con la esperanza de que ayuda a varios a no perder tiempo.

Problema: Al instalar el SDK de Windows Live ID para Web Autentication se reporta problemas de permisos que impiden finalizar la instalación.

Causa del Problema: Por un error en la compilación del archivo, el instalador requiere la existencia de los grupos User y Power User, como mi maquina esta con el sistema operativo en Español  no existen dichos usuarios (por eso siempre se recomienda no referenciar los grupos por nombres si no por el ID del Grupo, parece que este grupo de desarrollo de MS no lee el sitio de Patterns and Practices).

Solución: Crear dos grupos con los Nombres Users y Power Users, agregar su usuario (del dominio y de la maquina local), incluir de las políticas de la maquina los usuarios Autenticados e Interactivo (NT Authority\Interactive).

Cerrar la sesión, ingresar nuevamente y correr el Instalador.

Ahora sí debería poderlo instalar. 

WindowsLiveWebAuth

(despues de 3 días,  finalmente se instalo ;-))

 

Espero que sea de Ayuda

 

Juan Carlos Peláez

MCTS

Miembro del Microsoft Speaker Group Andino

Miembro de Microsoft Influencers Colombia

 

KeyWords: Windows Live ID, Live ID SDK, Problemas, Instalación, Permisos, Autenticación usando Windows Live ID, Autenticación usando Passport

Tuesday, October 02, 2007 12:53:48 PM (SA Pacific Standard Time, UTC-05:00)  #    Comments [0] - Trackback
.net | Articulos de Desarrollo | Web Services | Windows Live | Windows Live ID
# Friday, July 13, 2007
 
Durante el desarrollo de la nueva versión de nuestras aplicaciones usando arquitecturas distribuidas con WCF encontré los siguientes problemas en las herramientas de Visual Studio que quiero compartir aqui.
 
El primero, que muchos habran identificado, es que al generar el código usando la opción de nueva libreria de WCF en visual basic genera una clase datacontract1 que no tiene marcada ninguna de sus propiedades como datamember, por lo que cuando se publica el servicio y se genera el proxy esta clase no tiene ninguna propiedad publica que pueda trasmitirse con por el cable, esto se soluciona facilmente marcando como datamember la propiedad generada para que quede asi: (en negrillas lo que hay que adicionar)
 
<DataContract()> _
Public Class DataContract1
Private m_firstName As String
Private m_lastName As String
 
<DataMember()> _
Public Property FirstName() As String
Get
Return m_firstName
End Get
Set(ByVal value As String)
m_firstName = value
End Set
End Property
 
<DataMember()> _
Public Property LastName() As String
Get
Return m_lastName
End Get
Set(ByVal value As String)
m_lastName = value
End Set
End Property
End
Class
 
El segundo tiene que ver con el nombre por default para el namespace que coloca Visual Studio a los proyectos, este namespace genera un problema en la serialización de los objetos marcados como datacontract ya que estos llegan correctamente al servicio pero no estan inicializados, si se depura el cliente se ve correctamente creado el objeto pero en el servicio no estan los valores.
 
Este punto se puede resolver usando alguno de los siguientes procedimientos:
 
a. Eliminado el namespace colocado por default en el cliente, el host y el servicio. (usando las propiedades del proyecto dentro de visual studio).
b. al generar el proxy del servicio usando la herramienta svcutil.exe usar el modificar /n para indicar que se quiere generar un proxy con el namespace del cliente, algo como esto:
 
svcutil.exe *.wsdl *.xsd /namespace:*,MyNamespace /language:VB
 
siendo MyNamespace el nombre del namespace del cliente del servicio.
 
Estos problemas no se presentan cuando se usan servicios con tipos basicos del CRL como strings o enteros o en algun otro tipo de contracto (operacion,fault,etc), es unicamente para cuando tiene contratos de datos del tipo datacontract, tampoco se presentan en C#.
 
espero que sea de utilidad.
 
Juan Carlos Peláez
MCTS
 
KeyWords: WCF, svcutil, Visual Basic, Framework, net, Arquitectura, Componentes Distribuidos, Cliente, Servicio, Host, Microsoft
Friday, July 13, 2007 7:33:19 PM (SA Pacific Standard Time, UTC-05:00)  #    Comments [0] - Trackback
.net | Arquitectura | Articulos de Desarrollo | WCF | Web Services
# Tuesday, July 10, 2007

Aunque no sé si sea  un escenario muy común, (para nosotros en Gattaca si lo es), hay aplicaciones legacy escritas en ASP clásico que empiezan a integrarse con aplicaciones en .Net, bien sea como parte de un proceso paulatino de migración o como parte del proceso de agregar nuevas funcionalidades a la aplicación existente, en ambos escenarios una forma simple de integrar la aplicación asp con la nueva aplicación .net es exponer las nuevas funcionalidades de la aplicación .Net por medio de servicios web.

Aunque existe en La Red literatura respecto a la forma como debe hacerse esta invocación del web service desde la página web no todos los ejemplos apuntan a escenarios reales, el objetivo de este post es mostrar cómo debe realizarse esta integración para aplicaciones del mundo real.

1. El primer problema consisten en identificar cuáles son los tipos de datos que se van a transferir entre la aplicación asp y la aplicación .net, mi recomendación es pasar datos de tipos básicos del CRL, es decir, strings, longs, integers. Aunque es posible pasar objetos representados como XML para que después sean des-serializados por la aplicación .net esto complica bastante el escenario e incluye nuevos elementos de error. (Nosotros transferimos solo strings y creamos los objetos en la aplicación .net, para lo cual creamos los constructores adecuados)

2. El siguiente problema es identificar quien es el realmente el cliente del servicio, en la mayoría de los escenarios el cliente del servicio es código del lado del servidor, (el código que esta entre los tags <%%> es el código del servidor), también es posible que el cliente sea alguna de las funciones JavaScript de la página que se quiere invocar. (Este es el escenario que derivo en la existencia de AJAX Asynchronous JavaScript And XML).  Por ahora nos enfocaremos en el escenario donde el código del lado del servidor es quien consume el web service.

3. Ahora debemos seleccionar la forma como se comunicará la aplicación asp con el servicio web, básicamente hay dos opciones, usar SOAP, o usar el parser de xml (HTTP Post) que contiene un objeto poco conocido llamado MSXML2.ServerXMLHTTP que puede ayudarnos a realizar estas llamadas. Básicamente es un tema de gusto, facilidad y conveniencia, sin embargo como es necesario tener instalado el Toolkit de SOAP para poder usar los objetos de SOAP desde asp clásico y dicho componente se queda sin soporte a partir de Marzo 31  del 2008, entonces nosotros preferimos usar HTTP Post.

4. Bien lo siguiente es escribir el código del servicio web y modificar la página asp para que lo consuma, lo del servicio web no lo vamos a profundizar, es una clase con la decoración webservice con algunos métodos decorados webmethod, etc. un ejemplo sencillo puede ser algo como esto:

Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel

<System.Web.Services.WebService(Namespace:="http://MyNameSpace/services/MyProduct> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class WorkFlowServices
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function ServiceTest() As String
        Return "En Ejecucion..."
    End Function

    <WebMethod()> _
    Public Function MyMetodoconParametros(ByVal Client As String, ByVal UserID As Long, ByVal IDProcessCase As Long, _
                                                ByVal Sequence As Long, ByVal EntryDataType As String, ByVal IDEntryData As String, ByVal EntryData As String) As Long

...hacer algo, retornar algo.

    End Function

End Class 

5. Ahora como consumir este web service desde la página asp clásica, es algo como esto:

<%

Dim xmlhttp

Dim DataToSend

Dim postUrl

postUrl = "http://IPMyServer/Services/WorkFlowServices.asmx/MyMetodoconParametros"

DataToSend="Client=Tester&UserID=1&IDProcessCase=80&Sequence=0" & _

"&EntryDataType=TestWebService&IDEntryData=0&EntryData=1"

 

Response.write postURL

Response.write "<br>"

 

Set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")

xmlhttp.Open "POST",postUrl,false

xmlhttp.setRequestHeader "Content-Type","application/x-www-form-urlencoded"

xmlhttp.send DataToSend

 

Response.Write(xmlhttp.responseText)

%>

Lo importante de este segmento de código, es la forma como se construye la invocación del método, la variable postURL tiene la dirección del servicio web asi como el nombre del método que se va a invocar. Luego la variable DataToSend tiene la información de los valores que toman los diferentes parametros que se van a pasar al metodo del web service (la recolección de estos parámetros depende del tipo de uso e interfaz que se tenga con los usuarios pero puede ser la recolección de una forma usando request.form o la recolección de los parámetros del QueryString que invocó la páginas ASP).  

Otra cosa importante es la definición del encabezado en la linea xmlhttp.setRequestHeader "Content-Type","application/x-www-form-urlencoded" .

Listo, se invocó el web service, ahora el resultado puede recuperarse de una de estas propiedades: responseBody, responseStream, responseText, and responseXML., (nosotros usamos response.text que nos retorna todo el entity body como un stream)

Tips Súper Importantes:

· Cuando su cliente del servicio web sea el propio código asp ("del lado del servidor") se recomienda usar el objeto MSXML2.ServerXMLHTTP que ha sido diseñado y optimizado para comunicaciones entre servidores.

· El código anterior genera un error en la mayoría de los servicios web del framework 2.0, es un error del tipo "Request format is unrecognized for URL" o en español "Formato de solicitud no reconocido para la dirección URL" esto se debe a que los protocolos Get y Post estan deshabilitados por omisión (default) en las aplicaciones del framework 2.0 para todas las peticiones de orígenes diferentes a Localhost. (Esa es la razón por la que la página de prueba de los servicios web como se ve desde otra maquina no tiene el formulario Test Service), por lo tanto para que efectivamente se realice la invocación hay que habilitar estos protocoles, eso se hace incluyendo las siguientes líneas en el archivo web.config del servicio web de .net.

<system.web>

    <webServices>
        <protocols>
            <add name="HttpGet"/>
            <add name="HttpPost"/>
        </protocols>
    </webServices>

(...)

</system.web>

En este articulo hay más información del comportamiento de los protocolos, aunque solo habla del framework 1.1. también ocurren con en el framework 2.0.

Espero que sea de utilidad

 

Juan Carlos Peláez
MCTS

Keywords: Web Services, ASP Clasic, .Net, Framework 2.0, VB, "Formato de Solicitud no reconocido",

Tuesday, July 10, 2007 1:12:34 PM (SA Pacific Standard Time, UTC-05:00)  #    Comments [0] - Trackback
.net | Arquitectura | Articulos de Desarrollo | WCF | Web Services
Contácteme
mail: jpelaez at juanpelaez.com
Archivo
<November 2008>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
FeedBurner
Maps
Locations of visitors to this page
Sponsors
Acerca de...

Aviso Legal
Las opiniones expresadas en este sitio representan el punto de vista de Juan Peláez sobre diferentes temas y no representan la posición de Studiocom.com.Inc, Microsoft. o de cualquier otra compañía que haya contratado los servicios de consultoría de Juan Peláez

© Copyright 2008
Juan Carlos Peláez
Sign In

Technorati Profile
Estadísticas
Total Posts: 69
This Year: 40
This Month: 2
This Week: 0
Comments: 10
All Content © 2008, Juan Carlos Peláez
El tema 'Business' para DasBlog fue creado por Christoph De Baene (delarou) y modificado para espa�ol por Juan Peláez
Powered by FeedBurner