Recent posts:
Recent replies:

Hi Neil,

Using OAuth2 in a mirrored environment would require some additional scripting to keep the configuration in sync between mirror members, since as you note it's stored in %SYS.

The Server Configuration on the auth server won't be changing much over time so I'd recommend writing an installation script that sets up all relevant configuration. Below are some snippets from an installation class I'm using on a Caché authorization server:

ClassMethod CreateServerConfiguration(pOrigNamespace As %String = "%SYS", Output interval As %Integer, Output server) As %Status
{
    Set server = ##class(OAuth2.Server.Configuration).Open(.tSC)
    If $IsObject(server) {
        Set tSC = server.Delete()
        If $$$ISERR(tSC) Quit tSC
    }

    Set interval = 3600

    Set server = ##class(OAuth2.Server.Configuration).%New()
    Set server.Description = "Single Sign-On"
    Set issuer = ##class(OAuth2.Endpoint).%New()
    Set issuer.Host = ..#IssuerHost
    Set issuer.Prefix = ..#IssuerPrefix
    Set server.IssuerEndpoint = issuer

    Set scopes = ##class(%ArrayOfDataTypes).%New()
    Do scopes.SetAt("OpenID Connect","openid")
    Do scopes.SetAt("E-mail Address","email")
    Do scopes.SetAt("User Profile","profile")
    // Add whatever other custom scopes you need
    Set server.SupportedScopes = scopes

    Set server.AllowUnsupportedScope = 0
    Set server.SupportedGrantTypes = "APCI"
    Set server.ReturnRefreshToken = ""
    Set server.AudRequired = 0

    Set server.CustomizationRoles = "%DB_CACHESYS,%Manager"
    Set server.CustomizationNamespace = pOrigNamespace
    Set server.AuthenticateClass = ..#CustomAuthenticateClassName
    Set server.ValidateUserClass = ..#CustomValidateClassName
    Set server.GenerateTokenClass = "%OAuth2.Server.JWT"

    Set server.AccessTokenInterval = interval
    Set server.RefreshTokenInterval = 3*interval
    Set server.AuthorizationCodeInterval = 120
    Set server.ServerCredentials = ..#ServerX509Name
    Set server.SigningAlgorithm = "RS512"
    Set server.KeyAlgorithm = ""
    Set server.EncryptionAlgorithm = ""
    Set server.SSLConfiguration = ..#SSLConfig

    Quit server.Save()
}

ClassMethod CreateServerDefinition(Output server) As %Status
{
    Set tIssuer = ..#EndpointRoot

    Set server = ##class(OAuth2.ServerDefinition).%OpenId("singleton")
    Set:'$IsObject(server) server = ##class(OAuth2.ServerDefinition).%New()
    Set server.IssuerEndpoint = tIssuer
    Set server.AuthorizationEndpoint = tIssuer_"/authorize"
    Set server.TokenEndpoint = tIssuer_"/token"
    Set server.UserinfoEndpoint = tIssuer_"/userinfo"
    Set server.IntrospectionEndpoint = tIssuer_"/introspection"
    Set server.RevocationEndpoint = tIssuer_"/revocation"
    Set server.ServerCredentials = ..#ServerX509Name
    Quit server.%Save()
}

The client descriptions are likely to change over time as new clients are registered. I think to keep these in sync between mirror members you'll need to regularly export the relevant globals directly from the primary, transport them to the secondary, and import them into the %SYS namespace. Below are some methods that do the export and import:

ClassMethod ExportClientConfiguration(pDestFile As %String) As %Status
{
    new $namespace
    set $namespace = "%SYS"
    for type = "D","I" {
        set tList("OAuth2.Server.Client"_type_".GBL") = ""
        set tList("OAuth2.Client.Metadata"_type_".GBL") = ""
    }
    set tSC = ##class(%File).CreateDirectoryChain(##class(%File).GetDirectory(pDestFile))
    return:$$$ISERR(tSC) tSC
    return $System.OBJ.Export(.tList,pDestFile,,.errorlog)
}

ClassMethod ImportClientConfiguration(pSourceFile As %String) As %Status
{
    new $namespace
    set $namespace = "%SYS"
    return $System.OBJ.Load(.pSourceFile,,.errorlog)
}

You could use a task to do this regularly on a short schedule.

Thank you for the zbreak example and linking the tutorial. I've always wanted a way to set conditional breakpoints for debugging but never looked deep enough into the documentation to find it.

Thanks for the reply. How can my unit test configure a BPL process to call my mock operation instead of the real operation? Do I have to rewrite the business process to use indirection in the target of each <call> element and make the target a custom setting on the business host?

Followers:
Following:
Pravin has not followed anybody yet.
Global Masters badges: