You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:能否用Google自定义SAML App作为IDP适配ITfoxtec.Identity.Saml2?

问题解答

1. Google自定义SAML App与ITfoxtec.Identity.Saml2的兼容性

完全可以将Google自定义SAML App作为身份提供商(IDP)与ITfoxtec.Identity.Saml2配合使用,二者的SAML 2.0协议实现完全兼容。

2. 查找Google SAML App的Entity ID和ACR相关地址

登录Google Admin控制台,进入你已创建的自定义SAML应用,在"SAML设置"页面中获取以下信息:

  • Entity ID:在"身份提供商详情"板块下的"实体ID"字段,格式通常为https://accounts.google.com/o/saml2/idp?idpid=xxxxxx,直接复制即可。
  • ACR Url:这里你可能混淆了术语——ACR(Authentication Context Class Reference)是认证上下文标识,Google IDP并不单独提供ACR Url。如果你需要的是IDP的单点登录(SSO)端点地址,它和上述Entity ID是同一个URL;如果是指服务提供商(SP)的断言消费地址(ACS Url),那是你自己应用的地址(比如https://your-app-domain.com/Saml2/Acs),需要在Google SAML应用的"服务提供商详情"中配置这个地址。

3. ASP.NET中实现Google SAML SSO的简单示例

以下是基于ASP.NET Core + ITfoxtec.Identity.Saml2的极简实现步骤:

步骤1:安装依赖包

通过NuGet安装:

Install-Package ITfoxtec.Identity.Saml2.AspNetCore

步骤2:配置appsettings.json

添加SAML相关配置(替换占位符为你的实际信息):

"Saml2": {
  "EntityId": "https://your-app-domain.com/Saml2",
  "AssertionConsumerServiceUrl": "https://your-app-domain.com/Saml2/Acs",
  "SingleLogoutServiceUrl": "https://your-app-domain.com/Saml2/LogoutAcs",
  "IdP": {
    "EntityId": "Google的IDP Entity ID",
    "SingleSignOnUrl": "Google的SSO URL(同Entity ID)",
    "SigningCertificate": "从Google Admin下载的PEM格式证书内容"
  }
}

步骤3:注册SAML服务(Program.cs)

var builder = WebApplication.CreateBuilder(args);

// 注册SAML配置
builder.Services.AddSaml2(options =>
{
    builder.Configuration.GetSection("Saml2").Bind(options);
    // 若使用证书文件,可在此加载
    // options.IdP.SigningCertificate = new X509Certificate2("path-to-google-cert.pem");
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

步骤4:创建Saml2Controller

using ITfoxtec.Identity.Saml2;
using ITfoxtec.Identity.Saml2.MvcCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;

public class Saml2Controller : Controller
{
    private readonly Saml2Configuration _samlConfig;

    public Saml2Controller(IOptions<Saml2Configuration> samlConfig)
    {
        _samlConfig = samlConfig.Value;
    }

    // 发起SSO登录请求
    public IActionResult Login()
    {
        var binding = new Saml2RedirectBinding();
        binding.SetRelayStateUrl("/"); // 登录成功后跳转地址
        return binding.Bind(new Saml2AuthnRequest(_samlConfig)).ToActionResult();
    }

    // 处理IDP返回的SAML断言
    [HttpPost]
    public async Task<IActionResult> Acs()
    {
        var samlResponse = new Saml2AuthnResponse(_samlConfig);
        var binding = new Saml2PostBinding();

        binding.ReadSamlResponse(Request.ToGenericHttpRequest(), samlResponse);
        if (samlResponse.Status != Saml2StatusCodes.Success)
        {
            throw new InvalidOperationException($"SAML登录失败,状态码:{samlResponse.Status}");
        }
        binding.Unbind(Request.ToGenericHttpRequest(), samlResponse);

        // 创建用户会话
        await samlResponse.CreateSession(HttpContext, claimsTransform: p => p);

        return Redirect(samlResponse.RelayState);
    }

    // 发起注销请求
    public async Task<IActionResult> Logout()
    {
        if (!User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Index", "Home");
        }

        var binding = new Saml2RedirectBinding();
        var logoutRequest = new Saml2LogoutRequest(_samlConfig, User);
        return binding.Bind(logoutRequest).ToActionResult();
    }

    // 处理注销响应
    [HttpPost]
    public async Task<IActionResult> LogoutAcs()
    {
        var samlLogoutResponse = new Saml2LogoutResponse(_samlConfig);
        var binding = new Saml2PostBinding();

        binding.ReadSamlResponse(Request.ToGenericHttpRequest(), samlLogoutResponse);
        if (samlLogoutResponse.Status != Saml2StatusCodes.Success)
        {
            throw new InvalidOperationException($"SAML注销失败,状态码:{samlLogoutResponse.Status}");
        }
        binding.Unbind(Request.ToGenericHttpRequest(), samlLogoutResponse);

        // 清除本地会话
        await HttpContext.SignOutAsync();
        return RedirectToAction("Index", "Home");
    }
}

额外注意事项

  • 确保在Google Admin的SAML应用设置中,正确配置你的SP的Entity ID和Assertion Consumer Service Url。
  • 从Google Admin下载IDP的签名证书(PEM格式),将内容粘贴到配置的SigningCertificate字段,或直接加载证书文件。

内容的提问来源于stack exchange,提问作者Asad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 13:45:38