首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows-使用声明的MVC应用程序进行身份验证,多次调用身份验证并松开安全令牌cookie

Windows-使用声明的MVC应用程序进行身份验证,多次调用身份验证并松开安全令牌cookie
EN

Stack Overflow用户
提问于 2016-02-07 16:46:05
回答 1查看 1K关注 0票数 0

我正在开发基于Windows-authentication声明的MVC应用程序。我已经实现了IHttpModule (也称为"ClaimsTransformation模块“,用于调解身份)和自定义ClaimsAuthenticationManager (它向该标识添加了附加声明),如下所示。页面加载,我可以检索新增加的索赔,但很少有严重的问题.

problems是:

  1. 即使在初始页面加载时,我的自定义RomesClaimsAuthenticationManager.Authenticate方法也会被调用27+ times (我假设有些调用是并行/异步的)。
  2. FedAuth (SessionToken) cookie检查从不返回true,即使在SAM (SessionAuthenticationManager)将SesstionToken写入cookie之后--我可以看到它,但在下一次调用时(仍然是在原始页面加载期间)--如果打开其他页面,也会发生相同的情况。
代码语言:javascript
复制
public class RomesClaimsAuthorizationModule : IHttpModule, IDisposable
{

    public void Init(System.Web.HttpApplication application)
    {
        // intercept PostAuthenticationRequest to add custom logic
        application.PostAuthenticateRequest += TransformPrincipal;
    }

    private static void TransformPrincipal(object sender, EventArgs e)
    {

        var context = ((HttpApplication)sender).Context;

        // PROBLEM HERE - this is always false, even after cookie has been set
        // check if cookie with auth info about curr user already exists
        if (FederatedAuthentication.SessionAuthenticationModule != null && 
            FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
        {
            return;
        }
        else
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // this will pick up our custom Romes.Adminn.Security.RomesClaimsAuthenticationManager
                // it is specified in web.config, so our app will use it as default
                // which will add our custom additional claims to our principal
                var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager;
                if (transformer != null)
                {                    
                    var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, context.User as ClaimsPrincipal);

                    // generate cookie
                    SessionSecurityToken sst = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
                    sst.IsReferenceMode = true; // used when there are a lot of claims - will be faster
                    sst.IsPersistent = true;  

                    // write cookie to session
                    FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sst);

                    // write to context
                    context.User = transformedPrincipal;
                    Thread.CurrentPrincipal = transformedPrincipal;
                }

            }
        }
    }


}

定制ClaimsAuthenticationManager:

代码语言:javascript
复制
public class RomesClaimsAuthenticationManager : ClaimsAuthenticationManager
{

    // PROBLEM - THIS GETS HIT 27+ times on original page load
    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
    {
        if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true)
        {
            ((ClaimsIdentity)incomingPrincipal.Identity).AddClaim(new Claim(ClaimTypes.Email, "myTestEmail@email.com"));
            // i will be making a db call here to get add'l user info from DB, and then convert it into claims
        }
        return incomingPrincipal;
    }
}

Web.config文件:

代码语言:javascript
复制
<configSections>    
  <!--this is required for custom ClaimsAuthorizationManager-->
  <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  <!--this will allow us to write ClaimsPrincipal to a cookie, saving from calls to db on each request-->
  <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
...
<system.identityModel>
  <identityConfiguration>
    <claimsAuthenticationManager type="ROMES.Admin.Security.RomesClaimsAuthenticationManager, ROMES.Admin" />
  </identityConfiguration>
</system.identityModel>

<system.identityModel.services>    
  <federationConfiguration>
    <cookieHandler  mode="Default"  requireSsl="true" />
  </federationConfiguration>
</system.identityModel.services>
<system.web>
  <authentication mode="Windows"/>
  ...
  <authorization>
    <allow roles="WINDOWS\ROMES_Admins"/>
    <deny users="*" />
  </authorization>

  <!--must be in both here and system.webServer/modules-->
  <!--see here WHY: https://msdn.microsoft.com/en-us/library/gg638734.aspx-->
  <httpModules>
    <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />     
  </httpModules>

</system.web>
<system.webServer>

  <!-- same as in system.web/httpModules-->
  <modules>
    <add name="RomesClaimsAuthorizationModule" type="ROMES.Admin.Security.RomesClaimsAuthorizationModule"/>
    <!--this module will handle reading and writing cookie for identity/claims - so that there will be no need to call db every request for user info-->
    <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

  </modules>
  ...
</system.webServer>

我的主要问题是:(1)为什么我的身份验证块被多次调用;(2)为什么会话安全令牌cookie不持久--这似乎是对资源的浪费。

EN

回答 1

Stack Overflow用户

发布于 2016-04-21 09:36:37

在这里

代码语言:javascript
复制
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies)

更改为

代码语言:javascript
复制
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookie)

并查看条件是否开始为真,并且代码是否返回。

在David的注释:context替换为context.Request.Cookie之后编辑

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35256203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档