Sharepoint 2010 Form认证自定义登录页面,总是自动登录问题

说明

关于Sharepoint表单登录自定义页面网上有好多,这里也就不重复说了,我也是从网上找的代码,使用网上的代码正常登录是没有问题的,都是很正常的,但是有一点小细节,就是都是默认记住密码的。

这个也是客户提出来的,他们希望用户登录之后,每次关闭浏览器之后登录凭据就应该过期,让用户重新登录,网上的代码实现不了。

解决方法

这个问题应该怎么解决呢,Form认证一般都是把验证信息存在Cookie中,让Cookie在浏览器关闭的时候过期就可以了,我记得以前在做Asp.Net开发的时候是可以这么做的,现在都忘了,隐约记得应该是保存在Session中,可以实现关闭浏览器过期效果,方向有了,是不是在代码中可以设置把凭据保存到Session中呢?

网上找了好长时间也没有关于sharepoint登录关闭浏览器过期怎么做。突然想到Sharepoint默认页面有一个Rember Me这个东西,我就想是不是和这个东西有关系。

找到Sharepoint的DLL,反编译一下看看代码:默认登录的代码在”Microsoft.SharePoint.IdentityModel.DLL”中。

  SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
  fam.SetPrincipalAndWriteSessionToken(_SecurityToken)

SetPrincipalAndWriteSessionToken方法有两个重载:

public void SetPrincipalAndWriteSessionToken(SecurityToken securityToken);

public void SetPrincipalAndWriteSessionToken(SessionSecurityToken sessionToken, bool isSession);

一般时候网上提供的都是第一个,我们可以看出,第二个方法提供了是否使用Session来保存凭据,那么好了找到方向了。直接使用第二个重载就可以了。

当我写到“SessionSecurityToken”这个参数的时候,问题又来了,我们办法得到这个参数,参考微软的代码:

        /// <summary>
        /// 获取SessionToken
        /// </summary>
        /// <param name="_SecurityToken"></param>
        /// <returns></returns>
        private static SessionSecurityTokenCreatedEventArgs GetSessionToken(SecurityToken _SecurityToken)
        {
            GenericXmlSecurityToken genericXmlSecurityToken = _SecurityToken as GenericXmlSecurityToken;
            if (genericXmlSecurityToken != null)
            {
                _SecurityToken = GetSecurityToken(genericXmlSecurityToken);
            }

            IClaimsPrincipal claimsPrincipal = AuthenticateUser(_SecurityToken);
            SessionSecurityTokenCreatedEventArgs sessionSecurityTokenCreatedEventArgs = new SessionSecurityTokenCreatedEventArgs(new SessionSecurityToken(claimsPrincipal, null, new DateTime?(tk.ValidFrom), new DateTime?(tk.ValidTo))
            {
                IsPersistent = false
            });
            return sessionSecurityTokenCreatedEventArgs;
        }
        /// <summary>
        /// 微软方法,获取SecurityToken,不清楚微软为什么这么做
         /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        internal static SecurityToken GetSecurityToken(GenericXmlSecurityToken token)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
            SecurityToken result = null;
            SecurityTokenHandlerCollection securityTokenHandlerCollection = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
            using (XmlNodeReader xmlNodeReader = new XmlNodeReader(token.TokenXml))
            {
                result = securityTokenHandlerCollection.ReadToken(xmlNodeReader);
            }
            return result;
        }
        /// <summary>
        /// 获取声明
         /// </summary>
        /// <param name="securityToken"></param>
        /// <returns></returns>
        internal static IClaimsPrincipal AuthenticateUser(SecurityToken securityToken)
        {
            if (securityToken == null)
            {
                throw new ArgumentNullException("securityToken");
            }
            if (securityToken.SecurityKeys != null && securityToken.SecurityKeys.Count != 0)
            {
                throw new SecurityTokenException("Bearer token required.");
            }
            GenericXmlSecurityToken genericXmlSecurityToken = securityToken as GenericXmlSecurityToken;
            if (genericXmlSecurityToken != null)
            {
                securityToken = GetSecurityToken(genericXmlSecurityToken);
            }
            ServiceConfiguration serviceConfiguration = FederatedAuthentication.ServiceConfiguration;
            ClaimsIdentityCollection identityCollection = serviceConfiguration.SecurityTokenHandlers.ValidateToken(securityToken);
            string resourceName = null;
            if (HttpContext.Current != null)
            {
                resourceName = HttpContext.Current.Request.RawUrl;
            }
            return serviceConfiguration.ClaimsAuthenticationManager.Authenticate(resourceName, new ClaimsPrincipal(identityCollection));
        }

最后正确调用方法:

SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
fam.SetPrincipalAndWriteSessionToken(sessionSecurityTokenCreatedEventArgs.SessionToken, true);

 

总结

要想实现关闭浏览器凭据过期我们需要把凭据存储在Session中,根据上面提供的代码获取SessionToken。

这个连接下的方法也不错。

https://social.msdn.microsoft.com/Forums/en-US/06ec9060-4b98-412c-b6d5-7a7139b36839/autologin-with-forms-authentication?forum=sharepointdevelopmentprevious

posted @ 2015-09-24 16:01  qiumc  阅读(835)  评论(0编辑  收藏  举报