查找

文章
· 一月 5 阅读大约需 1 分钟

クロスプラットフォームで開発する際のちょっとした落とし穴

MacOS(Linux)とWindows両方で動作するObjectScriptプログラムを開発する際に、よくやらかしてしまうミスを共有します。

WindowsとUNIX系のファイルシステムの1つの違いは、ディレクトリのセパレータです。

UNIX系は、/(スラッシュ)

Windows系は、\(バックスラッシュ)

です。

ファイルを読み書きするプログラムでセパレータをOS別に選択するという以下のようなコードをよく書くのですが、

if ($system.Version.GetOS() = "UNIX") {
    set sep = "/"
}
else {
    set sep = "\"
}

 

ここでこのバックスラッシュをキーボードで入力すると、日本語キーボードの場合、バックスラッシュの代わりに¥(円マーク)が入力されてしまいます。

ソースコードがSJISの場合は、これでも問題ないのですが、クロスプラットフォームで開発する場合は、UTF8で通常作成するので、Macで動かすと問題ないのにWindowsで動かすとエラーになるということがちょくちょく起こります。

そして、これは意外に間違いに気づきにくいです。

ちなみにPythonでは、どちらでも/を使っておけば問題ないので、こんな問題は起こることはないと思います。

3 条新评论
讨论 (3)1
登录或注册以继续
文章
· 一月 5 阅读大约需 3 分钟

Generating JWT without access to system x509 cert/keys

If you want to generate JWT from x509 cert/key, any operation (including reading) on %SYS.X509Credentials requires U on %Admin_Secure resource.%Admin_Secure is required because %SYS.X509Credentials is persistent, and it's implemented this way to prevent all users from accessing private keys.

If %Admin_Secure resource is not available at runtime, you can use the following workaround.

Upon reviewing the code for JWT generation, I discovered that the JWT code utilizes %SYS.X509Credentials solely as a source of runtime data for PrivateKey, PrivateKeyPassword, and Certificate. As a workaround, you can use a runtime non-persistent implementation of the X.509 interface, exposing just these properties. If you're using interoperability Cert/PK can be stored in credentials for secure access:

Class User.X509 Extends %RegisteredObject
{

Property PrivateKey As %VarString;

Property PrivateKeyPassword As %String;

Property Certificate As %VarString;

Property HasPrivateKey As %Boolean [ InitialExpression = {$$$YES} ];

ClassMethod GetX509() As User.X509
{
    set x509 = ..%New()
    set x509.PrivateKey = ..Key()
    set x509.Certificate = ..Cert()
    quit x509
}

/// Get X509 object from credential.
/// Username is a Cert, Password is a Private Key
ClassMethod GetX509FromCredential(credential) As User.X509
{
    set credentialObj = ##class(Ens.Config.Credentials).%OpenId(credential,,.sc)
    throw:$$$ISERR(sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)
    
    set x509 = ..%New()
    set x509.PrivateKey = credentialObj.Password
    set x509.Certificate = credentialObj.Username
    quit x509
}

ClassMethod Key()
{
    q "-----BEGIN RSA PRIVATE KEY-----"_$C(13,10)
    _"YOUR_TEST_KEY"_$C(13,10)
    _"-----END RSA PRIVATE KEY-----"
}

ClassMethod Cert() As %VarString
{
    q "-----BEGIN CERTIFICATE-----"_$C(13,10)
    _"YOUR_TEST_CERT"_$C(13,10)
    _"-----END CERTIFICATE-----"
}

}

And you can generate JWT the following way:

ClassMethod JWT() As %Status
{
    Set sc = $$$OK

    //Set x509 = ##class(%SYS.X509Credentials).GetByAlias("TempKeyPair")
    Set x509 = ##class(User.X509).GetX509()
    
    Set algorithm ="RS256"
    
    Set header = {"alg": (algorithm), "typ": "JWT"}
    Set claims= {"Key": "Value" }
    
    #; create JWK
    Set sc = ##class(%Net.JSON.JWK).CreateX509(algorithm,x509,.privateJWK)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    #; Create JWKS
    Set sc = ##class(%Net.JSON.JWKS).PutJWK(privateJWK,.privateJWKS)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    Set sc = ##Class(%Net.JSON.JWT).Create(header,,claims,privateJWKS,,.pJWT)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }
    
    Write pJWT
	Return sc
}

Alternatively you can use dynamic object to skip class creation, in that case it would look like this:

ClassMethod JWT(credential) As %Status
{
    Set sc = $$$OK

    //Set x509 = ##class(%SYS.X509Credentials).GetByAlias("TempKeyPair")
    Set credentialObj = ##class(Ens.Config.Credentials).%OpenId(credential,,.sc)
    throw:$$$ISERR(sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)
    
    Set x509 = {
        "HasPrivateKey": true,
        "PrivateKey": (credentialObj.Password),
        "PrivateKeyPassword":"",
        "Certificate":(credentialObj.Username)
    }

    Set algorithm ="RS256"
    
    Set header = {"alg": (algorithm), "typ": "JWT"}
    Set claims= {"Key": "Value" }
    
    #; create JWK
    Set sc = ##class(%Net.JSON.JWK).CreateX509(algorithm,x509,.privateJWK)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    #; Create JWKS
    Set sc = ##class(%Net.JSON.JWKS).PutJWK(privateJWK,.privateJWKS)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    Set sc = ##Class(%Net.JSON.JWT).Create(header,,claims,privateJWKS,,.pJWT)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }
    
    Write pJWT
    Return sc
}
讨论 (0)1
登录或注册以继续
文章
· 一月 5 阅读大约需 1 分钟

Como obter informações do servidor/instância

Olá a todos,

Como parte do desenvolvimento de uma API para saber a qual instância do IRIS está conectada, encontrei alguns métodos para obter informações sobre o servidor que podem ser úteis.

Obter o nome do servidor: $SYSTEM.INetInfo.LocalHostName()

Obter o IP do servidor: $SYSTEM.INetInfo.HostNameToAddr($SYSTEM.INetInfo.LocalHostName())

Obter o nome da instância: $PIECE($SYSTEM,":",2)

Assim, criei o seguinte código como uma classe BS:

Class St.Common.Api Extends (%CSP.REST, Ens.BusinessService)
{
{

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
	<Route Url="/check" Method="GET" Call="Check"/>
</Routes>
}

ClassMethod Check() As %Status
{
	set serverInfo = {}
	set serverInfo.ServerName = $SYSTEM.INetInfo.LocalHostName()
	set serverInfo.ServerIP = $SYSTEM.INetInfo.HostNameToAddr($SYSTEM.INetInfo.LocalHostName())
	set serverInfo.Instance = $PIECE($SYSTEM,":",2)
	
	write serverInfo.%ToJSON()
	quit $$$OK
}
}

Chamando o método:

localhost:52773/common/api/check

{
  "ServerName": "LAPTOP-KURRO-3",
  "ServerIP": "11.52.197.99",
  "Instance": "HEALTHCONNECT"
}

Espero que seja tão útil para você quanto foi para mim.

Atenciosamente.

讨论 (0)1
登录或注册以继续
公告
· 一月 5

InterSystems Change Control: Tier 1 Basics – Virtual January 21-23, 2026 / Registration space available

InterSystems Change Control: Tier 1 Basics - Virtual January 21-23, 2026

  • This 3-day course is only for current users of the Change Control Record (CCR) application. 
  • Use InterSystems Change Control Record (CCR) to progress code changes and debug problems.
  • CCR users will learn how to safely progress changes to code and interfaces as well as troubleshoot common issues. 
  • The CCR application is primarily used by customers hosted or implemented by InterSystems. 
  • General use of Source Control with InterSystems products is not covered. 
  • This course is applicable to all developers and interface specialists using CCR and will not cover Tier 2 usage for InterSystems TrakCare® application specialists.

 

SELF REGISTER HERE

讨论 (0)1
登录或注册以继续
摘要
· 一月 5

Publicações Desenvolvedores InterSystems, Dezembro 29, 2025 - Janeiro 04, 2026, Resumo

Artigos
#InterSystems IRIS
Quando considerar o uso de useIrisFsGroup em suas implantações do IKO
Por Evandro Wendt
Aproveitando o Server Manager ao criar extensões do VS Code que se conectam a servidores InterSystems
Por Evandro Wendt
Arquivos temporários e singletons: limpem o que vocês gerarem.
Por Evandro Wendt
#DIM vs SET – ObjectScript
Por Evandro Wendt
Como encontrar um texto específico em ObjectScript
Por Evandro Wendt
API nativa para Demos ObjectScript
Por Evandro Wendt
Exportando dados de configuração de Interoperabilidade para CSV
Por Evandro Wendt
embeddedpy-bridge: Um kit de ferramentas para Embedded Python
Por Evandro Wendt
Construindo fluxos de integração de forma simples com o InterSystems IRIS
Por Evandro Wendt
Carregando dados em servidores (locais ou remotos) diretamente pelo VS Code.
Por Evandro Wendt
Exemplo ECP "Reloaded" – Implantação de várias instâncias do IRIS em arquitetura ECP
Por Evandro Wendt
EnsLib.SQL.Snapshot não é limpo durante a depuração de mensagens quando é usado na mensagem de resposta.
Por Evandro Wendt
Declarações/Estatísticas SQL desatualizadas (Ou: Por que eu tenho um enorme ^rINDEXSQL global?)
Por Evandro Wendt
Visualize as configurações do seu servidor InterSystems usando o Structurizr
Por Evandro Wendt
CCR: Bloqueio das transições markMoveToXXXXComplete e markCANCELComplete quando houver ItemSets não implantados
Por Evandro Wendt
Exibir os Itens de Configuração de Produção com Status
Por Evandro Wendt
Como comparar o conteúdo de duas globais
Por Evandro Wendt
#Outro
#Open Exchange
Perguntas
Dezembro 29, 2025 - Janeiro 04, 2026Week at a GlanceInterSystems Developer Community