首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

基於 Geneva 框架構建安全令牌服務 (STS):主動/被動聯合、聲明轉換與自定義擴展

     編輯:關於.NET

Microsoft 「Geneva」框架(後整合為 WIF/IdentityModel)提供構建自定義 STS 的完整編程模型。本文詳細演示如何實現主動/被動 STS、配置 WS-Trust 端點、處理聲明轉換、擴展令牌處理器,並對比 Geneva Server 的企業級特性。

STS 核心角色與協議

  • IP-STS (Identity Provider STS):驗證用戶身份,頒發含聲明的 SAML 令牌。
  • RP-STS (Relying Party STS):接收 IP-STS 令牌,轉換聲明後向 RP 頒發新令牌(跨域聯合)。
  • 協議基石:WS-Trust (Issue/Validate/Renew/Cancel)、WS-Federation (主動/被動請求者配置文件)、SAML 1.1/2.0 令牌格式。

主動 STS 實現 (Windows Client 場景)

1. 核心類繼承 SecurityTokenService

public class IdentitySTS : SecurityTokenService {
    public IdentitySTS(SecurityTokenServiceConfiguration config) : base(config) { }

    protected override Scope GetScope(IClaimsPrincipal principal, RequestSecurityToken request) {
        var scope = new Scope(request);
        // 驗證 AppliesTo (RP 地址),返回加密憑證
        scope.EncryptingCredentials = GetCredentialsForAppliesTo(request.AppliesTo);
        // 簽名憑證 (STS 私鑰)
        scope.SigningCredentials = new X509SigningCredentials(CertUtil.Get("CN=IPKey"));
        return scope;
    }

    protected override IClaimsIdentity GetOutputClaimsIdentity(IClaimsPrincipal principal, RequestSecurityToken request, Scope scope) {
        var id = new ClaimsIdentity();
        id.Claims.Add(new Claim(ClaimTypes.Name, principal.Identity.Name));
        id.Claims.Add(new Claim(ClaimTypes.Role, "Users"));
        // 可擴展:查詢數據庫/AD 獲取角色、權限、Email 等聲明
        return id;
    }
}

2. 配置與託管

public class IdentitySTSConfiguration : SecurityTokenServiceConfiguration {
    public IdentitySTSConfiguration() : base("https://localhost:8010/sts") {
        TokenIssuerName = "https://localhost:8010/sts";
        SigningCredentials = new X509SigningCredentials(CertUtil.Get("CN=IPKey"));
        SecurityTokenService = typeof(IdentitySTS);
        // 程序化添加端點 (替代 config 文件)
        TrustEndpoints.Add(new ServiceHostEndpointConfiguration("WSTrustFeb05", new WSHttpBinding(), typeof(IWSTrustFeb2005SyncContract)));
        TrustEndpoints.Add(new ServiceHostEndpointConfiguration("WSTrust13", new WSHttpBinding(), typeof(IWSTrust13SyncContract)));
    }
}

// 自託管
var host = new WSTrustServiceHost(new IdentitySTSConfiguration());
host.Open();

// IIS 託管 (.svc)
/* @ServiceHost Factory="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory" Service="STS.IdentitySTSConfiguration" */

3. 安全令牌處理器擴展 (自定義認證)

<microsoft.identityModel>
  <securityTokenHandlers>
    <remove type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler, ..." />
    <add type="Microsoft.IdentityModel.Tokens.MembershipUserNameSecurityTokenHandler, ...">
      <usernameSecurityTokenHandlerRequirement membershipProvider="CustomProviders.CustomMembershipProvider" />
    </add>
  </securityTokenHandlers>
  <claimsAuthenticationManager type="STS.CustomClaimsAuthenticationManager, STS" />
</microsoft.identityModel>

自定義 UserNameSecurityTokenHandler 重寫 ValidateToken 實現非 Windows 認證(如數據庫驗證),返回 ClaimsIdentityCollection。

被動 STS 實現 (Browser/WEB 場景)

1. 架構差異

  • STS 作為 ASP.NET 應用部署,需 SSL 保護。
  • 默認頁面 (Default.aspx) 承載 FederatedPassiveTokenService 控件,處理登入/登出/令牌頒發/重定向。
  • ASP.NET 認證模組 (Forms/Windows/CardSpace) 負責用戶身份驗證,驗證後導向默認頁面繼續聯合流程。

2. 關鍵配置

<!-- Default.aspx -->
<idfx:FederatedPassiveTokenService ID="FedPassive" runat="server" Service="STS.IdentityProviderSTSConfiguration, STS" />

<!-- web.config -->
<authentication mode="Forms" />
<authorization> <deny users="?" /> </authorization>
<microsoft.identityModel>
  <federatedAuthentication enabled="true" />
</microsoft.identityModel>
<modules>
  <add name="SessionAuthentication" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, ..." />
</modules>

3. ReplyToAddress 設置

protected override Scope GetScope(...) {
    var scope = base.GetScope(...);
    scope.ReplyToAddress = scope.AppliesToAddress + "/default.aspx";  // RP 登陸頁
    return scope;
}

聲明轉換:聯合安全的核心

場景 1:IP-STS 本地轉換

用戶以任意憑證登入 → IP-STS 產生初始聲明 → 轉換為 RP 通用聲明 (Role/Action:Create/Read/Update/Delete) → 頒發令牌。

IP-STS 聲明轉換

場景 2:RP-STS 上下文相關轉換

RP 僅請求最小聲明識別用戶 → 業務操作時 (如 DeleteCustomer) → RP 調用 RP-STS 申請上下文聲明 (Action:Delete) → 授權決策。

RP-STS 聲明轉換

場景 3:跨域聯合轉換

用戶域 B 登入 IP-STS → 獲取域 A RP-STS 信任的聲明 (RPClaim) → RP-STS 轉換為域 A 專用聲明 → RP 授權。

跨域聯合聲明轉換

前提:IP-STS 與 RP-STS 建立信任,協商頒發聲明契約。

隱私保護模式

避免直接暴露敏感聲明 (如 Age) → RP 請求衍生聲明 (如 IsOver13) → STS 僅頒發衍生聲明,原始數據不出邊界。

總結與建議

  • Geneva 框架適合輕量級自定義 STS,企業級生產環境優先考慮 Geneva Server (ADFS) 或 Azure AD,擁有完整的管理、審計、高可用、災備能力。
  • 主動/被動 STS 通信流程一致,核心差異在傳輸綁定 (WS-Trust SOAP vs HTTP Form Post) 與令牌類型 (Holder-of-Key vs Bearer)。
  • 聲明轉換是實現最小權限、隱私保護、跨域互信的關鍵樞紐,設計時需嚴格契約化。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved