Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La soluzione orientata ai servizi usa Enterprise Single Sign-On (SSO) sia per archiviare i valori di configurazione che per gestire le credenziali per i sistemi back-end. Per ridurre la latenza, la soluzione usa una cache locale per i valori di configurazione. La soluzione aggiorna la cache ogni cinque minuti.
In molte applicazioni, gli adapter gestiscono le operazioni SSO, incluso il recupero di un ticket SSO, il riscatto del ticket e l'uso delle credenziali per ottenere l'accesso all'applicazione affiliata. Tuttavia, la versione inline della soluzione orientata ai servizi non usa adattatori. Deve usare SSO attraverso il codice.
Questo argomento descrive il meccanismo di memorizzazione nella cache usato dalla soluzione, nonché il modo in cui la versione integrata della soluzione utilizza SSO (Single Sign-On) dal codice.
Memorizzazione nella cache locale dei valori di configurazione
La soluzione orientata ai servizi usa due oggetti , ConfigPropertyBag e ConfigParameters, per gestire i valori di configurazione. La classe ConfigPropertyBag contiene i valori e viene usata solo dalla classe ConfigParameters . La classe ConfigParameters viene usata dalle altre parti della soluzione per recuperare i parametri di configurazione. Entrambe le classi si trovano nello spazio dei nomi Microsoft.Samples.BizTalk.WoodgroveBank.ConfigHelper .
Annotazioni
La soluzione orientata ai servizi corregge l'intervallo di aggiornamento della cache a 300 secondi (5 minuti). È invece possibile impostare l'intervallo di aggiornamento della cache come proprietà configurabile in questa soluzione. Questa operazione viene eseguita nella soluzione Di gestione dei processi aziendali. Per altre informazioni su come la soluzione gestisce l'accesso SSO, vedere Uso efficiente dell'accesso Single Sign-On nella soluzione di gestione dei processi di business. Si noti che, in questo caso, una modifica nell'intervallo di aggiornamento non viene applicata fino a quando la cache non viene aggiornata alla fine dell'intervallo precedente.
ConfigPropertyBag include i metodi seguenti:
| Metodo | Descrizione |
|---|---|
| Leggi | Recupera un valore per una determinata proprietà. |
| Scrittura | Assegna un valore a una proprietà. |
La classe usa un'istanza di .NET NameValueCollection per contenere i valori. I due metodi di accesso implementano l'interfaccia IPropertyBag dallo spazio dei nomi Microsoft.BizTalk.SSOClient.Interop . La classe ConfigPropertyBag è una classe interna e usata solo dalla classe ConfigParameters .
Annotazioni
I nomi delle chiavi nel contenitore delle proprietà non fanno distinzione tra maiuscole e minuscole. L'oggetto NameValueCollection sottostante usa confronti con hash senza distinzione tra maiuscole e minuscole e senza distinzione tra maiuscole e minuscole.
L'applicazione usa la classe ConfigParameters per gestire i valori di configurazione SSO. La classe ha i metodi e gli attributi pubblici seguenti:
| Metodo o attributo | Descrizione |
|---|---|
| SSOConfigParameter | Enumerazione per specificare i parametri di configurazione. |
| OttieniParametriConfigurazione | Metodo utilizzato per recuperare un valore per un determinato parametro. Usa SSOConfigParameter per indicare il parametro . |
La classe ConfigParameters usa la classe Timer .NET e una funzione delegato per configurare l'aggiornamento di ConfigPropertyBag:
private static Timer cacheRefreshTimer;
private static ISSOConfigStore ssoConfigStore;
private static ReaderWriterLock syncLock;
// Cache refresh interval in milliseconds
private const int CacheRefreshInterval = 5 * 60 * 1000;
private static ConfigPropertyBag ssoPropBag;
static ConfigParameters()
{
ssoConfigStore = new ISSOConfigStore();
ssoPropBag = new ConfigPropertyBag();
syncLock = new ReaderWriterLock();
ssoConfigStore.GetConfigInfo(SSO_CONFIG_APP,
SSO_IDENTIFIER_NAME, SSOFlag.SSO_FLAG_RUNTIME,
ssoPropBag);
cacheRefreshTimer = new Timer(
new TimerCallback(ConfigParameters.cacheRefreshCallback),
null, CacheRefreshInterval, CacheRefreshInterval);
}
Si noti che il costruttore statico inizializza le variabili membro statiche consentendo così l'uso di metodi di classe senza creare un'istanza della classe . Il costruttore crea istanze dell'archivio di configurazione SSO (ISSOConfigStore), il contenitore delle proprietà di configurazione (ConfigPropertyBag) e un blocco di sincronizzazione (ReaderWriterLock) usato per controllare l'accesso a ConfigurationPropertyBag durante gli aggiornamenti e le letture. Il costruttore usa quindi GetConfigInfo per recuperare i valori di configurazione SSO e inserirli nel contenitore delle proprietà. Infine, il costruttore crea un oggetto Timer che, dopo l'intervallo specificato, chiama la funzione delegato cacheRefreshCallback.
La funzione del delegato Timer è relativamente semplice:
private static void cacheRefreshCallback(object state)
{
// Disable the timer until we are done loading the cache.
cacheRefreshTimer.Change(Timeout.Infinite, CacheRefreshInterval);
// Put the data from SSO in a new property bag so that
// we don't have to lock the property bag and block it from being
// used. The SSO call is a remote call and may take a while.
ConfigPropertyBag propBag2 = new ConfigPropertyBag();
ssoConfigStore.GetConfigInfo(SSO_CONFIG_APP,
SSO_IDENTIFIER_NAME, SSOFlag.SSO_FLAG_RUNTIME, propBag2);
// Get a writer lock before updating the cached values.
syncLock.AcquireWriterLock(Timeout.Infinite);
try
{
ssoPropBag = propBag2;
}
finally
{
syncLock.ReleaseWriterLock();
}
// Enable the timer.
cacheRefreshTimer.Change(CacheRefreshInterval,
CacheRefreshInterval);
}
Si noti che il metodo di callback di aggiornamento della cache disabilita il timer in modo che il metodo possa essere eseguito fino all'interno. Si noti anche l'uso dei lucchetti per controllare l'accesso al sacchetto delle proprietà. ReaderWriterLock è la scelta migliore qui, progettata per i casi in cui sono presenti più letture rispetto alle scritture. Si noti anche che il blocco, syncLock, è statico e dichiarato a livello di classe che tutti i thread condividono la stessa istanza singola di esso.
Utilizzo del Single Sign-On da Code
Quando si usa l'accesso Single Sign-On dal codice, il codice deve assumere il ruolo dell'adattatore, ovvero recuperare il ticket SSO dal messaggio, riscattare il ticket per ottenere il nome utente e la password per il sistema back-end e, infine, usare il sistema back-end. La soluzione orientata ai servizi esegue questa operazione tramite il metodo GetPendingTransactionsResponse dell'oggetto PendingTransactionsCaller .
Il metodo viene visualizzato come segue:
public static PendingTransactionsResponse GetPendingTransactionsResponse(XLANGMessage requestMsg)
{
try
{
// Get config parameter values.
int ptTimeout = Convert.ToInt32(
ConfigParameters.GetConfigParameter(
ConfigParameters.
SSOConfigParameter.
PENDING_TRANSACTIONS_INLINE_TIMEOUT
)
);
string ptURL = ConfigParameters.GetConfigParameter(
ConfigParameters.
SSOConfigParameter.
PENDING_TRANSACTIONS_URL
);
string ssoAffliateApp = ConfigParameters.
GetConfigParameter(ConfigParameters.
SSOConfigParameter.
PENDING_TRANSACTIONS_SSO_AFFILIATE_APP
);
// Redeem the SSO ticket and get the userid/password to
// use to interact with Pending Transaction System.
// Extract the ticket…
string msgTicket = (string)requestMsg.
GetPropertyValue(typeof(BTS.SSOTicket));
// and the user name of the originating user.
string originatorSID = (string)requestMsg.
GetPropertyValue(
typeof(
Microsoft.BizTalk.XLANGs.BTXEngine.OriginatorSID
)
);
string pendTransUserName;
// Now, redeem the ticket.
string[] pendTransCredential =
ssoTicket.RedeemTicket(
ssoAffliateApp,
originatorSID,
msgTicket,
SSOFlag.SSO_FLAG_NONE,
out pendTransUserName
);
PendingTransactionsRequest req =
(PendingTransactionsRequest)requestMsg[0].
RetrieveAs(
typeof(PendingTransactionsRequest)
);
PendingTransactionsResponse resp;
using (PendingTransactionsWebService
svc = new PendingTransactionsWebService())
{
svc.Url = ptURL;
svc.Timeout = ptTimeout;
// The web service uses basic authentication, so we
//need to send the user id and password in the request.
CredentialCache credCache = new CredentialCache();
NetworkCredential credentialToUse =
new NetworkCredential(
pendTransUserName, pendTransCredential[0]
);
credCache.Add(new Uri(svc.Url), "Basic", credentialToUse);
svc.Credentials = credCache;
resp = svc.GetPendingTransactions(req);
}
return resp;
}
catch (System.Net.WebException webEx)
{
if (webEx.Status == WebExceptionStatus.Timeout)
{
throw new PendingTransactionsTimeoutException();
}
else
{
Trace.WriteLine("Other Net.WebException: "
+ webEx.ToString()
+ (null == webEx.InnerException ? "" :
("Inner Exception: "
+ webEx.InnerException.ToString())
)
);
throw;
}
}
catch(System.Exception ex)
{
Trace.WriteLine("Other Exception: "
+ ex.ToString()
+ (null == ex.InnerException ? "" :
("Inner Exception: "
+ ex.InnerException.ToString())
)
);
throw;
}
}
Il metodo inizia recuperando le informazioni di configurazione, incluso l'URL, per il sistema back-end e il nome dell'applicazione back-end (affiliata).
Per riscattare il ticket, il metodo deve estrarre il ticket e il nome utente originale richiesto dal messaggio. Il messaggio contiene il ticket come una delle proprietà del contesto del messaggio, BTS. SSOTicket. Per altre informazioni, vedere Message Context Properties (Proprietà del contesto del messaggio ) nelle informazioni di riferimento sullo spazio dei nomi delle API per sviluppatori e indicazioni sull'interfaccia utente. Il metodo estrae anche OriginatorSID dalle proprietà del contesto del messaggio. Con il ticket e il nome dell'originatore in mano, il metodo chiama il metodo RedeemTicket sul ticket per recuperare le credenziali.
Il resto del codice crea una cache .NET NetworkCredential per le credenziali e chiama il servizio Web back-end.
Annotazioni
Poiché il nome utente e la password tornano dall'accesso Single Sign-On in testo non crittografato, è necessario ridurre al minimo la durata delle variabili che contengono tali informazioni. Si noti che il codice dichiara le variabili delle credenziali all'interno di un blocco try . In questo caso, le variabili scadono all'uscita dal blocco try .
Vedere anche
Evidenziazione dell'implementazione della soluzione orientata ai servizi