WIF(WSFederationAuthentication)如何知道我是哪个用户?

时间:2017-02-01 19:36:32

标签: asp.net authentication forms-authentication wif adfs

我已经负责找出允许用户在基于表单的网站中进行身份验证的方法。我们的企业IT部门已经建立了一个开发adfs服务器,并且依赖方信任已经建立到我们的开发环境之一。

我一直在阅读和寻找教程大约两周,所以我不是专家,我似乎无法理解STS(我们的ADFS服务器)应该如何确定哪个用户请求身份验证。

我一直在关注Wiktor Zychla的博客,因为它实际上包含了代码示例,并且与大多数其他教程相比,更少使用web.config。 (http://www.wiktorzychla.com/2014/11/simplest-saml11-federated-authentication.html

就我所见,这是管道。

  1. 用户进入登录页面。
  2. Page_Load自动将用户重定向到ADFS
  3. 用户获得身份验证并重定向回登录页面
  4. 在Page_Load中,我然后使用某些令牌并使用它来进行授权 用户。
  5. 将用户重定向到需要身份验证的页面。
  6. 我对网站所做的代码和Web.config更改:

       protected void Page_Load(object sender, System.EventArgs e)
    {
        var sam = FederatedAuthentication.SessionAuthenticationModule;
        var fam = new WSFederationAuthenticationModule();
        fam.FederationConfiguration = FederatedAuthentication.FederationConfiguration;
        var request = new HttpContextWrapper(this.Context).Request;
    
        if (UseADFS)
        {
            // is this the response from the STS
            if (!fam.IsSignInResponse(request))
            {
                // no
    
                // the STS
                fam.Issuer = WsFederationIssuerName;
                // the return address
                fam.Realm = WsRealm;
                fam.Reply = WsReply;
    
                var req = fam.CreateSignInRequest(string.Empty, null, false);
    
                // go to STS
                Response.Redirect(req.WriteQueryString());
            }
    
            // is this the response from the STS
            else
            {
                // yes, get the SAML token
                var securityToken = fam.GetSecurityToken(request);
    
                var config = new SecurityTokenHandlerConfiguration
                {
                    CertificateValidator = X509CertificateValidator.None,
                    IssuerNameRegistry = new CustomIssuerNameRegistry()
                };
                config.AudienceRestriction.AudienceMode = AudienceUriMode.Never;
    
                var tokenHandler = new SamlSecurityTokenHandler
                {
                    CertificateValidator = X509CertificateValidator.None,
                    Configuration = config
                };
    
                // validate the token and get the ClaimsIdentity out of it
                var identity = tokenHandler.ValidateToken(securityToken);
    
                var principal = new ClaimsPrincipal(identity);
    
                var token = sam.CreateSessionSecurityToken(principal, string.Empty,
                      DateTime.Now.ToUniversalTime(), DateTime.Now.AddMinutes(20).ToUniversalTime(), false);
    
                sam.WriteSessionTokenToCookie(token);
    
                if (identity[0].IsAuthenticated)
                {
                    //string email = principal.Claims.Where(x => x.Type == ClaimTypes.Email).Select(x => x.Value).SingleOrDefault();
                    string name = principal.Claims.Where(x => x.Type == ClaimTypes.Name).Select(x => x.Value).SingleOrDefault();
    
                    CustomClaimsObject claim = new CustomClaimsObject(name, principal);
                    doSigninWork(true, claim);
                }
            }
        }
        else if (!this.IsPostBack && !fam.IsSignInResponse(request))
        {
            Session.Abandon();
        }
    }
    <configSections>
        <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
    </configSections>
    
    
        <httpModules>    
            <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler"/>
        </httpModules>
    
        <modules>
            <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler"/>
        </modules>
    
      <system.identityModel>
      </system.identityModel>
    
      <system.identityModel.services>
          <federationConfiguration>
              <cookieHandler requireSsl="false" />
          </federationConfiguration>
      </system.identityModel.services>
    
        <authentication mode="Forms">
          <forms loginUrl="Public/invalidlogin.aspx?err=sessiontimeout" protection="All" requireSSL="false" slidingExpiration="true"/>
        </authentication>
    

    STS如何确定谁在请求身份验证?我没有发布任何相关的用户信息。我应该为我的要求添加一些东西吗?或者上下文是否应该有相关数据?或者ADFS框是否需要登录用户输入凭据的位置?

    现在当我导航到用户(通过按钮点击) https://xxx-xxx.xxxxx.xxxxxx.com/adfs/ls/ 时,我收到此错误。

    Encountered error during federation passive request. 
    
    Additional Data 
    
    Protocol Name: 
    wsfed 
    
    Relying Party: 
    
    
    Exception details: 
    Microsoft.IdentityServer.Web.CookieManagers.InvalidContextException: MSIS7001: The passive protocol context was not found or not valid. If the context was stored in cookies, the cookies that were presented by the client were not valid. Ensure that the client browser is configured to accept cookies from this website and retry this request.
       at Microsoft.IdentityServer.Web.Protocols.GenericProtocolRequest.ParseEncodedRequestParts(String[] encodedRequestParts)
       at Microsoft.IdentityServer.Web.Protocols.GenericProtocolRequest..ctor(String encodedGenericRequest)
       at Microsoft.IdentityServer.Web.Protocols.WSFederation.WSFederationProtocolHandler.GetOriginalRequestFromResponse(ProtocolContext context)
       at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
       at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)
    

    有人能踢我正确的方向吗?对于有经验的人,我确信我遗漏了一些明显的东西。

    更新

    使用adfs登录工作。但现在我在退出时有点挣扎。 我的注销码如下。基本上发生的事情是,即使在我尝试使用下面的代码“注销”之后,对我的声明身份的身份验证仍然是正确的。我从ADFS发送给依赖方的唯一声明是电子邮件声明。不确定这是否有所作为。

    WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule;
    string signoutUrl = (WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(WsFederationIssuerName, eURL.BuildURL(), null));
    WSFederationAuthenticationModule.FederatedSignOut(new Uri(signoutUrl), null);
    

    更新2:

    所以我意识到退出工作正常。但是,在重定向到我的注销页面之前,似乎ADFS正在重定向到我的登录页面。这导致登录代码再次运行,从而触发对ADFS的另一个声明。有办法阻止这个吗?或者是一种了解我是否来自adfs注销的方法?

    更新3:

    通过在if(UseADFS)子句周围包装if语句来检查问题,以检查我来自哪里。

    if(request.UrlReferrer.Authority.Contains(authority))
    

    我只是检查一下我来自的地方是我的服务器(你的adfs域名)vs(你的网站域名)。这与放在我的重定向网址中的参数一起足以破译用户是否正在退出或登录。

0 个答案:

没有答案