#眉標=SQL Server 2008、Service Broker、SOA #副標=實用SQL Server 2008(5) #大標=資料庫的訊息交換平台 ─ Service Broker(上) #作者=文/圖 胡百敬 ===<反灰>============= DECLARE @conversationHandle UNIQUEIDENTIFIER --寄送訊息到目的服務 BEGIN DIALOG @conversationHandle FROM SERVICE [來源服務] TO SERVICE '目的服務' ON CONTRACT [合約] ================ ============= 程式1 USE master; GO --若在相同的網域內,可以採用 --Active Directory的Windows認證 --或在同一台機器上,有兩個 SQL Server 執行個體 --則可以採用 Windows 帳戶 /* IF EXISTS (SELECT * FROM sys.endpoints WHERE name = N'InitiatorEndpoint') DROP ENDPOINT InitiatorEndpoint; GO CREATE ENDPOINT InitiatorEndpoint STATE = STARTED AS TCP ( LISTENER_PORT = 4022 ) FOR SERVICE_BROKER (AUTHENTICATION = WINDOWS); --允許遠端SQL Server 服務執行個體所使用的Windows 帳號 --透過這個端點連結 CREATE LOGIN [SomeDomain\SomeOne] FROM Windows; GRANT CONNECT ON ENDPOINT::InitiatorEndpoint TO [SomeDomain\SomeOne] */ --在此以沒有AD的方式驗證 --採用憑證認證,可在兩個SQL Server執行個體安裝相同的憑證 CREATE MASTER KEY ENCRYPTION BY PASSWORD = N''; GO CREATE CERTIFICATE AuthCertificate AUTHORIZATION DBO WITH SUBJECT = N'Authentication Certificate', EXPIRY_DATE = N'12/31/2010'; go BACKUP CERTIFICATE AuthCertificate TO FILE = N'C:\Certs\AuthCertificate.cer' WITH PRIVATE KEY(FILE='C:\Certs\AuthCertificate', ENCRYPTION BY PASSWORD='') GO IF EXISTS (SELECT * FROM sys.endpoints WHERE name = N'InitiatorEndpoint') DROP ENDPOINT InitiatorEndpoint; GO --一個SQL Server 執行個體只能有一個同類型的端點 --各資料庫內所定義的Service Broker服務需共用執行個體的端點 CREATE ENDPOINT InitiatorEndpoint STATE = STARTED AS TCP ( LISTENER_PORT = 4022) FOR SERVICE_BROKER (AUTHENTICATION = CERTIFICATE AuthCertificate, ENCRYPTION=SUPPORTED); --上述將兩個SQL Instance安裝相同Certificate 的作法是偷懶的方式 --正確的方式應該是一端備份出憑證,但不需要備份Private Key --然後將憑證複製到本機來,執行以下的授權 --這裡麻煩的是 Login 無法擁有憑證,而 User 無法授權透過端點連接 --所以需要先建立 Login 再建立對應於該 Login 的 User --授權 Login 可以透過端點連接,User 擁有對方的憑證 /* CREATE LOGIN EventTargetLogin WITH PASSWORD='' CREATE USER EventTargetUser FOR LOGIN EventTargetLogin CREATE CERTIFICATE TargetEndPointCert AUTHORIZATION EventTargetUser FROM FILE='C:\EventTargetUser'; GRANT CONNECT ON ENDPOINT::InitiatorEndpoint TO EventTargetLogin */ ================ ===<反灰>============= ENCRYPTION = { DISABLED | SUPPORTED | REQUIRED } [ALGORITHM { RC4 | AES | AES RC4 | RC4 AES } ] ================ ==<表>=========== 表1:兩個Service Broker端點對加解密的要求所產生之交互影響 端點1 端點2 加密與否 DISABLED SUPPORTED 否 DISABLED DISABLED 否 DISABLED REQUIRED 發生錯誤 SUPPORTED SUPPORTED 是 SUPPORTED REQUIRED 是 REQUIRED REQUIRED 是 REQUIRED DISABLED 發生錯誤 ================ ===<反灰>============= 程式2 USE master; GO IF EXISTS (SELECT * FROM sys.databases WHERE name = N'InitiatorDB') DROP DATABASE InitiatorDB; GO --Service Broker的服務是在資料庫等級下 CREATE DATABASE InitiatorDB; GO USE InitiatorDB; GO --為保護用來解密傳遞訊息的憑證 --需先建立資料庫的 Master Key CREATE MASTER KEY ENCRYPTION BY PASSWORD = N''; GO --建立使用者,以擁有憑證,但這個使用者不需要讓外界登入 --僅用在Service Broker溝通 CREATE USER InitiatorUser WITHOUT LOGIN; GO CREATE CERTIFICATE InitiatorCertificate AUTHORIZATION InitiatorUser WITH SUBJECT = N'Initiator Certificate', EXPIRY_DATE = N'12/31/2010'; --備份憑證,以安裝到與之對話的資料庫內 --只需有憑證資料和Public Key,不需輸出Private Key BACKUP CERTIFICATE InitiatorCertificate TO FILE = N'C:\Certs\InitiatorCertificate.cer'; ================