A Code Example For SAML

博客围绕SAML标准展开,该标准用于用户与多个发行方间交换安全登录信息,允许发行方采用如PKI、哈希或密码等认证方法。文中给出了一个符合SAML的请求示例,请求发行方进行密码认证,还展示了发行方的响应断言。

A Code Example

Because the SAML standard is designed only for the exchange of secure sign-on information between a user, or "relying party," and multiple issuing parties, it allows issuing parties to use their own chosen methods of authentication for example, PKI, hash, or password.

Here, a sample SAML-compliant request is sent from a relying party requesting password authentication by the issuing party.

<samlp: Request ...>

  <samlp: AttributeQuery>
 
    <saml: Subject>
      <saml: NameIdentifier
        SecurityDomain="sun. com"
        Name="rimap"/>
    </ saml: Subject>
   
    <saml: AttributeDesignator
      AttributeName="Employee_ ID"
      AttributeNamespace="sun. com">
    </ saml: AttributeDesignator>
  </ samlp: AttributeQuery>
</ samlp: Request>

 


In response, the issuing authority asserts that the subject (S) was authenticated by means (M) at time (T).

<samlp: Response
  MajorVersion="1" MinorVersion="0"
  RequestID="128.14.234.20.90123456"
  InResponseTo="123.45.678.90.12345678"
  StatusCode="/features/2002/05/Success">
 
  <saml: Assertion
    MajorVersion="1" MinorVersion="0"
    AssertionID="123.45.678.90.12345678"
    Issuer="Sun Microsystems, Inc."
    IssueInstant="2002- 01- 14T10: 00: 23Z">
   
    <saml: Conditions
      NotBefore="2002- 01- 14T10: 00: 30Z"
      NotAfter="2002- 01- 14T10: 15: 00Z" />
     
    <saml: AuthenticationStatement
    AuthenticationMethod="Password"
    AuthenticationInstant="2001- 01- 14T10: 00: 20Z">
   
      <saml: Subject>
        <saml: NameIdentifier
          SecurityDomain="sun. com"
          Name="rimap" />
      </ saml: Subject>
    </ saml: AuthenticationStatement>
  </ saml: Assertion>
</ samlp: Response>

 

### C# 项目集成 SAML2 单点登录 为了在 C# 项目中实现基于 SAML2 的单一登录 (SSO),通常会借助第三方库来简化开发过程。一个广泛使用的开源库是 `ComponentSpace.SAML2`,它提供了丰富的功能用于处理 SAML 断言、协议消息以及 Web 浏览器/POST 绑定等。 #### 安装 ComponentSpace.SAML2 库 通过 NuGet Package Manager 或者命令行安装该库: ```bash Install-Package ComponentSpace.SAML2 ``` #### 设置服务提供方(SP) 创建一个新的 ASP.NET Core MVC 应用程序作为 SP 并配置必要的设置项。这涉及到定义实体 ID 和断言消费者服务 URL 等参数。 ```csharp using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); // 添加Cookie认证中间件 services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie() .AddSaml2(options => Configuration.Bind("Saml2", options)); } ``` 在此基础上还需要修改 appsettings.json 文件以包含具体的 Saml2 配置节: ```json "Saml2": { "IdPMetadataUrl": "https://example.com/idp/metadata", "EntityId": "urn:aspnetcore-saml-example-sp", "AssertionConsumerServiceUrl": "/Auth/Saml2/Acs" }, ``` 其中 IdPMetadataUrl 是身份提供商元数据的位置;EntityId 表示当前应用程序的身份标识符;而 AssertionConsumerServiceUrl 则指定了接收来自 IdP 响应的具体路径。 #### 处理 SAML 登录请求与响应 接下来,在控制器内编写逻辑发起针对 Identity Provider (IdP) 的身份验证挑战并解析返回的结果。 ```csharp using ComponentSpace.SAML2.Protocols; using ComponentSpace.SAML2.WebBrowserBindings; [ApiController] [Route("[controller]")] public class AuthController : ControllerBase { private readonly ISaml2Configuration _samlConfig; public AuthController(ISaml2Configuration samlConfig){ _samlConfig = samlConfig; } /// <summary> /// 发起 SAML 认证流程. /// </summary> [HttpGet("/Login")] public IActionResult Login(){ var authnRequest = new AuthenticationRequest(_samlConfig); return Redirect(WebBrowserBinding.Send(authnRequest, Request.Scheme, $"{Request.Host}{_samlConfig.AssertionConsumerServiceUrl}")); } /// <summary> /// 接收 SAML 身份验证响应. /// </summary> [HttpPost("/Acs"), ValidateAntiForgeryToken] public async Task<IActionResult> Acs([FromForm] string SAMLResponse){ if (!string.IsNullOrEmpty(SAMLResponse)){ try { var responseMessage = await WebBrowserPostBinding.Receive(Request.BodyReader.AsStream(), CancellationToken.None); if(responseMessage is Response response && !response.Status.Failed()){ foreach(var attributeStatement in response.Assertions.SelectMany(a=>a.AttributeStatements)) foreach(Attribute attribute in attributeStatement.Attributes) User.Claims.AddRange(attribute.Values.Select(v=>new Claim(attribute.Name,v))); return RedirectToAction("Index","Home"); }else{ ModelState.AddModelError("", $"Failed to authenticate with message {response?.Status.StatusCode.Value}"); } }catch(Exception ex){ ModelState.AddModelError("",ex.Message); } } return View(); } } ``` 上述代码片段展示了如何构建一个基本的 SAML 请求发送给 IdP,并且当接收到成功的 SAML 响应后提取用户的声明信息[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值