検索

お知らせ
· 2024年5月20日

Winners of the Vector Search, GenAI and ML Contest

Hi Community,

It's time to announce the winners of the Vector Search, GenAI and ML Contest

Thanks to all our amazing participants who submitted 15 applications 🔥 

Experts Nomination

🥇 1st place and $5,000 go to the BG-AppealAI app by @Maria Nesterenko@Katsiaryna Shaustruk@Maria Gladkova

🥈 2nd place and $3,000 go to the iris-medicopilot app by @José Pereira, @Henrique Dias, @Henry Pereira

🥉 3rd place and $1,500 go to the IRIS AI Studio app by @Ikram Shah

🏅 4th place and $750 go to the iris-health-coach app by @Zacchaeus Chok, @Crystal Cheong

🏅 5th place and $500 go to the companies-search app by @Julio Momente, @Davi Massaru Teixeira Muta, @Lucas Fernandes 

🌟 $100 go to the HackUPC24_Klìnic app by @Tanguy Vansnick

🌟 $100 go to the geo-vector-search app by @Robert Cemper 

🌟 $100 go to the AriticleSimilarity  app by @xuanyou du

🌟 $100 go to the iris-VectorLab app by @Muhammad Waseem

🌟 $100 go to the DNA-similarity-and-classify app by @Davi Massaru Teixeira Muta@Nicole Raimundo

Community Nomination

🥇 1st place and $1,000 go to the iris-medicopilot app by @José Pereira, @Henrique Dias, @Henry Pereira

🥈 2nd place and $750 go to the BG-AppealAI app by @Maria Nesterenko@Katsiaryna Shaustruk@Maria Gladkova

🥉 3rd place and $500 go to the iris-image-vector-search app by @shan yue

🏅 4th place and $300 go to the AriticleSimilarity  app by @xuanyou du

🏅 5th place and $200 go to the companies-search app by @Julio Momente, @Davi Massaru Teixeira Muta, @Lucas Fernandes 

Our sincerest congratulations to all the participants and winners!

Join the fun next time ;)

5 Comments
ディスカッション (5)2
続けるにはログインするか新規登録を行ってください
お知らせ
· 2024年5月20日

【精彩会议回放】区域医疗信息互联互通新发展研讨会在深圳举办

为推动《“十四五”全民健康信息化规划》全面实施,充分发挥国家医疗健康信息互联互通标准化成熟度评测工作对区域医疗信息交换促进作用,为医疗数据合规高效流通使用奠定坚实基础。《中国卫生信息管理杂志》社主办、深圳市卫生健康信息协会协办、InterSystems中国承办的区域信息互联互通新发展研讨会于5月11日在深圳举办。

国家卫生健康委统计信息中心胡建平副主任线上参会并致辞、广东省卫生健康委员会事务中心傅承主副主任、深圳市卫生健康信息协会林德南会长参加会议并致辞。胡建平副主任在视频致辞中强调了医疗健康信息互联互通标准化成熟度测评对区域全民健康信息化和智慧医院建设起到的重要作用,总结了互联互通标准化成熟度测评主要开展的四方面工作,指出下一步工作要从网络通、应用通、数据通等三个维度持续发力,通过叠加区块链等信息技术,实现互联互通从1.0阶段向2.0阶段跃迁,赋能卫生健康事业高质量发展。

查看精彩内容回放:欢迎扫描下图中的二维码或点击此处如果您已报名过此次会议,使用报名时的手机号码即可登录查看,如首次登录,需填写报名信息后查看

 

 

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
お知らせ
· 2024年5月20日

有奖调研结果公布!开发者社区(中文版)成员最常用的代码托管平台是GitHub

Hi 开发者们,

近期我们举办的有奖调研得到了大家的踊跃支持,现将结果分享如下——

 

调研奖励

以下参与者获得此次调研奖励,请于5月31日前通过后台与我联系,或将您的快递地址发送到邮箱claire.zheng@intersystems.com,我们将于近期陆续寄出奖品。

AirTag

@liu bo (https://cn.community.intersystems.com/user/liu-bo)

充气颈枕

@water huang (https://community.intersystems.com/user/water-huang)

@he hf  (https://cn.community.intersystems.com/user/he-hf)

桌面吸尘器

@YuHao Wan (https://cn.community.intersystems.com/user/yuhao-wan)

@Yongfeng Hou (https://cn.community.intersystems.com/user/yongfeng-hou)

@zhu liang (https://cn.community.intersystems.com/user/zhu-liang)

@qing he (https://community.intersystems.com/user/qing-he)

@Qi Wang (https://cn.community.intersystems.com/user/qi-wang-0)
 

再次感谢大家的积极参与!

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
ディスカッション (5)3
続けるにはログインするか新規登録を行ってください
記事
· 2024年5月19日 10m read

Proteger los datos: Se un mejor cerrajero

Buenas a todos,

 

en capítulos anteriores, vimos como "Como controlar el acceso a tus recursos con OAuth2". En este primer artículo explicábamos como preparar un acceso seguro a nuestros recursos utilizando la potente herramienta que nos ofrece Intersytems del servidor de Autenticación. Al finalizar el mismo, comentábamos que si quisiéramos podríamos aplicar un control extra a este acceso y esto nos lleva a este artículo, por lo que seguiremos el siguiente índice:

1.- Introducción

   1.1..- De donde venimos

2.- Problema

   2.1.- ¿Cómo funciona la llave (Token)?

   2.2.- ¿Qué es una hoja de registro (LookUp Table)?

   2.3.- ¿Cómo construyo las cerraduras?

   2.4.- Cómo avisar a la policía de intrusos

 

1.- Introducción

Para empezar, situemos el problema a resolver:

Llevado a una situación más común imaginemos estar en una vivienda compartida, al cual cada inquilino accede al piso con la llave de la puerta de entrada, pero luego dentro de casa, cada habitación no tuviera llave, por lo que cualquier inquilino podría entrar en la habitación de cualquier otro y ¡no creemos que sea para dejar regalos!

Llegados a este punto, tendremos que poner cerraduras en todas las puertas y asegurar que cada inquilino solo pueda acceder a su habitación. ¡Saquemos al cerrajero que llevamos dentro!

Os dejo un pequeño video que de forma conceptual explica nuestro problema y el resultado de nuestra solución:

 

1.1.-De dónde venimos

Partimos de un servidor de autenticación (puerta de entrada) y un servidor de Recursos (la vivienda). En el servidor de autenticación vamos a tener 2 clientes dados de alta, cada uno con su usuario y su contraseña. Por otro lado, nuestro ESB que hace de servidor de recursos tendrá la labor de consultar los recursos determinados (habitaciones) para cada cliente. Por lo tanto, tenemos:

  • Cliente 1 (inquilino 1)
  • Cliente 2 (inquilino 2)
  • Recursos Cliente 1 (habitación de inquilino 1)
  • Recursos Cliente 2 (habitación de inquilino 2)

 

A continuación un diagrama de flujo del problema encontrado:

2.- Problema

Con la solución actual, nos encontramos con el problema de seguridad de datos, pues, si el cliente 2 pudiera conocer los datos de la petición del cliente 1, Con pasar su propia autorización (llave de la puerta de entrada) hacia los recursos, de la puerta hacia dentro, tendría libertad para acceder a los recursos (habitaciones) que quiera. El propietario de la vivienda nos ha pedido que pongamos una cerradura en cada puerta, así que vamos con ello.

A continuación, se indican los pasos a seguir para ser mejores cerrajeros.

2.1.- ¿Cómo funciona la llave (Token)?

            El Servidor de Autenticación, una vez recibe un usuario y una contraseña válidos, nos devolverá un token con el siguiente formato:

{

    "access_token""eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJqdGkiOiJodHRwczovL2F1dGhzcnZyLnNjcy1zYWx1ZC5vcmc6NTc3NzYvb2F1dGgyLmdqQnZqR01JQzJqeVBYZW12dW5EWW1vTnJnMCIsImlzcyI6Imh0dHBzOi8vYXV0aHNydnIuc2NzLXNhbHVkLm9yZzo1Nzc3Ni9vYXV0aDIiLCJzdWIiOiJ5WUZIZElGWDQyZEVEV3FhZHhzWFJxbmZtZW1IVEVZYVFlQ09JbWRKVXpRIiwiZXhwIjoxNzE2MTU0Mjk4LCJhdWQiOiJ5WUZIZElGWDQyZEVEV3FhZHhzWFJxbmZtZW1IVEVZYVFlQ09JbWRKVXpRIn0.",

    "token_type""bearer",

    "expires_in"60,

    "scope""my/scope"
}

Este “Access_token” que viene en base64 se compone de información interesante para nuestro objetivo. Sabiendo que este token se genera por JWT, una vez tratado, vemos que se compone de:

  • Header
  • Payload

Header

Se compone de:

{

  "typ": "JWT",

  "alg": "none"
}

 

Payload

Se compone de:

{

  "jti": "https://authsrvr.org:57775/oauth2.gjBvjGMIC2jyPXemvunDYmoNrg0",

  "iss": "https://authsrvr.org:57775/oauth2",

  "sub": "yYFHdIFX42dEDWqadxsXRqnfmemHTEYaQeCOImdJUzQ",

  "exp": 1716154298,

  "aud": "yYFHdIFX42dEDWqadxsXRqnfmemHTEYaQeCOImdJUzQ"
}

 

Del payload el dato que nos vamos a quedar es el “aud”, ya que este dato es el usuario registrado en el servidor de autenticación que hemos creado previamente.

Para más información sobre este contenido, podéis consultar la documentación oficial de IS: (https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=%25SYS.OAuth2.Validation)

 

2.2.- ¿Qué es una hoja de registro (LookUp Table)?

No profundizaremos en este momento en las LoopUp Tables, lo que, si nos interesa saber en este punto, es que son unas tablas internas de cada namespace, en las cuales podemos guardar datos en el formato “clave/valor”.

Para más información sobre este contenido, podéis consultar la documentación oficial de IS:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ECONFIG_other_lookup_tables

 

2.3.- ¿Cómo construyo las cerraduras?

En este punto juntemos los 2 puntos anteriores, es decir, con el escenario actual, tenemos:

                -              Un dato del Token: “aud”

                -              Una tabla interna que almacena datos: “clave/valor”

Como responsables de la seguridad, sabemos que a este cliente solo hay que dejarle acceder a sus propios recursos, por lo que para ello, en la LookUp table, vamos a guardar:

-              Clave: el “aud”

-              Valor: el condicionante de acceso a los recursos. En este ejemplo pongamos “1”.

 

Ahora que ya tenemos preparados los "materiales", nos toca construir la cerradura. Para ello explicamos a continuación los pasos a Seguir:

2.3.1.-  Recepción del Token

2.3.2.-  Extracción y validación del “aud”

 

2.3.1.-  Recepción del Token

Partimos para el ejemplo de un servicio REST que tendrá los siguientes parámetros:

Method MISERVICIO(pInput As %Stream.Object, Output pOutput As %Stream.Object, indicadorRecursos As %String(MAXLEN=""))As %Status

La información que vamos a requerir viene en el pInput y el indicadorRecursos. En el inicio de nuestro servicio observemos las siguientes líneas y lo que hace cada una:

{
    //Necesitamos sacar la cabecera "Authorization" de la petición REST
    set authorization = $tr(pInput.GetAttribute("authorization"),"")

    //Necesitamos sacar Token
    set token = $PIECE(authorization,"Bearer ",2)

    //Necesitamos validar el Token. Este apartado lo vamos a obviar en esta ocasión.
    set respuesta = ..ResServer(token)
    if (respuesta = 1){ Avanzar en el servicio } else{ Devolver error }

    //Necesitamos validar el “aud”
    set audValidado = ..ValidarUsernameOAUTH2(token,indicadorRecursos,.pOutput)

    //Si el “aud” es válido, podemos avanzar, sino salimos con el mensaje de respuesta que configuremos
    if (audValidado = 0)
    {
        quit ERROR            
    }
}

Como podemos ver, en la línea de validación del "aud" nos encontramos con la llamada a un método (ValidarUsernameOAUTH2) el cual os expongo a continuación.

 

2.3.2.-  Extracción del “aud”

En el siguiente método podemos ver paso a paso como se extrae y valida el "aud".

ClassMethod ValidarUsernameOAUTH2(token As %String(MAXLEN=""), indicadorRecursos As %String(MAXLEN=""), Output pOutput As %Stream.Object) As %Boolean
{
 set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
   
 // Buscamos el cliente de recursos
 Set client = ##class(OAuth2.Client).Open("resserver",.sc)
 If client  = "" Quit      
 // Inicializamos nuestra referencia para acceder a los recursos, pues si no cambia de valor, nunca podremos acceder a los recursos
 set codigoRecursosOAUTH2 = ""
 try{
  // Convertir JWT a objeto 
  set sc = ..JWTToObject(client,token,.securityParameters,.jsonObject)

  // Extraemos el “aud” del JSON que generamos al convertir el Token
  set usuarioOAUTH2 = jsonObject.aud

  // Extraemos de la LookUpTable que creamos en el paso anterior, el Valor que nos da el usuario que hemos extraído del Token. Si este valor es “”, quiere decir que no existe el usuario. Si existe, extraemos el Valor. Este valor es el que tendremos que enfrentar con el indicadorRecursos que tenemos en la entrada. Pues si estos no coinciden, querrá decir que el usuario está intentando acceder a recursos a los cuales no le hemos autorizado acceder.
  set codigoRecursosOAUTH2 = ##class(Util.TablasMaestras).getValorMaestra("SERVIDORAUTH.VALIDACION",usuarioOAUTH2)

 }catch{
  // Si hay errores, devolvemos una respuesta de error de acceso
  set response             = ##class(Mensajes.Response.Autorización.DatosResponse).%New()
  set response.codigo      = "-4"
  set response.descripcion = “Error de acceso"

  set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.response,,,,"aeloqtuw")
   
  // Enviamos el JSON con cabeceras
  Do:$$$ISOK(tSC) pOutput.SetAttribute("Content-Type","application/json")
  do pOutput.SetAttribute("Access-Control-Allow-Origin","*")
  do pOutput.SetAttribute("Access-Control-Allow-Credentials","true")
  do pOutput.SetAttribute("Access-Control-Allow-Methods","GET")
  do pOutput.SetAttribute("Access-Control-Allow-Headers","request,Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
 }

 // Si hubo error, significa que el token es incorrecto. Por lo tanto devolvemos un 0
 if (codigoRecursosOAUTH2 = ""){
    Quit '$$$OK                           
 }
 // Si la consulta a la LoopUp Table nos devolvió datos, debemos hacer ahora la validación de este valor.
 if (codigoRecursosOAUTH2 '= ""){
    // Si son distintos, significa que el aud NO es de estos recursos
    if (codigoRecursosOAUTH2 '= indicadorRecursos){
     set response             = ##class(Mensajes.Response.Autorización.DatosResponse).%New()
     set response.codigo      = "-3"
     set response.descripcion = “Consulta no Autorizada"
     set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.response,,,,"aeloqtuw")
    
     // Enviamos el JSON con cabeceras
     Do:$$$ISOK(tSC) pOutput.SetAttribute("Content-Type","application/json")
     do pOutput.SetAttribute("Access-Control-Allow-Origin","*")
     do pOutput.SetAttribute("Access-Control-Allow-Credentials","true")
     do pOutput.SetAttribute("Access-Control-Allow-Methods","GET")
     do pOutput.SetAttribute("Access-Control-Allow-Headers","request,Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")

  // Si son distintos, el método responde un 0
     Quit '$$$OK                                                          
    }
 }

 // Si son iguales, el método responde un 1
 quit $$$OK
}

Aclarando este apartado:

Supongamos que el indicadorRecursos de entrada viene a "2". Cuando vayamos a comparar el valor obtenido de la LoopUpTable ("1") con este valor, no coincidirán, por lo que no será posible acceder a los recursos. En cambio, si este valor de entrada es "1", si coincidirá y podrá acceder a los mismos.

Llegados a este punto, ya habríamos aplicado la cerradura (seguridad) a nuestra primera habitación (recursos). Para el resto de habitaciones, bastaría con repetir los mismos pasos para el resto de clientes/recursos.

2.4.- Cómo avisar a la policía de intrusos

Una vez detectado quien puede acceder o no a los recursos, podemos plantearnos monitorizar si alguien se esta pasando de listillo intentando acceder a recursos que no le corresponden. Para ello, podemos hacer uso de las herramientas de Intersystems para el envío de emails, notificaciones push, o incluso alimentar cuadros de mando y tener un mayor control de estos accesos incorrectos. Estas alertas deben configurarse en el momento que vamos a devolver un "0", pues es el momento donde tenemos los datos de acceso así como la respuesta del acceso no permitido.

 

La redacción de este artículo se ha planteado de forma esquematizada para que pueda ser adaptada a cualquier aplicación que puedan plantear. Se ha dejado indicado el código mínimo para que puedan entender y reutilizar de forma lo mas práctica posible. Os prometo que si seguís las indicaciones paso a paso para entender el proceso, ¡empezareis a poner cerraduras por doquier!

Finalmente espero que les sea de utilidad, ¡y que se conviertan en mejores cerrajeros!

Muchas gracias por el tiempo que han dedicado a esta lectura.

PD:Por favor, no duden en plantear cuestiones que ayuden a mejorar la redacción y explicación del mismo por si algo no ha quedado correctamente entendido.

3 Comments
ディスカッション (3)3
続けるにはログインするか新規登録を行ってください