码迷,mamicode.com
首页 > 其他好文 > 详细

ABP集成WIF实现单点登录

时间:2017-07-12 00:59:54      阅读:1041      评论:0      收藏:0      [点我收藏+]

标签:文件中   setting   刷新   app   ges   href   bsp   iis   out   

ABP集成WIF实现单点登录

参考

ojlovecd写了三篇关于WIF文章。

使用WIF实现单点登录Part III —— 正式实战 

使用WIF的一些开源示例。

https://github.com/obhita/PROCenter/tree/master/ProCenter.LocalSTS/STS

https://github.com/primaryobjects/SingleSignOn

https://github.com/shinpou/Windows-Identity-Foundation-Tutorial/tree/master/Learning%20SSO

WSFederation and SAML library for Java based web applications

https://github.com/auth10/auth10-java

WIF配置过程中的一些问题

1、WIF授权

MVC项目中使用[Authorize],注解方式鉴权。

webform项目中使用配置文件方式鉴权。

技术分享
<system.web>
     <authorization>
        <deny users="?" />
      </authorization>
</system.web>
View Code

2、密钥集合不存在

Exception: System.Security.Cryptography.CryptographicException
Message: 密钥集不存在。

解决方法:

C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys这个目录授权的时候出错了,一直报这个错误
“将安全信息应用到以下对象时发生错误 拒绝访问”,为ereryone用户分配完全控制权限,密钥集的错误就解决了。

3、部署时,出现

用户代码未处理 System.Security.Cryptography.CryptographicException 错误解决方法

解决方法:

IIS 应用程序池--选中你网站的所配置的应用程序池--右键 选择 “高级配置” --将“加载用户配置文件” 设置为True 。

4、thumbprint值

配置文件中<add thumbprint="xxxxxxxxxx" name="sts" />的值,使用IIS服务器证书中的指纹值。复制粘贴会带一些特殊字符,还是手敲吧!

在ABP中集成

User.Identity && User.Identity.IsAuthenticated并不依赖Session。
Web.config文件设置或者浏览器请求时候删除ASP.NET_SessionId只要保留.AspNet.ApplicationCookie存在请求身份一样能通过验证。
<system.web>
    <sessionState mode="Off" />
</system.web>

RP站

RP OnAuthentication鉴权:

        protected override void OnAuthentication(AuthenticationContext filterContext)
        {
            if (filterContext.HttpContext == null)
                throw new ArgumentNullException("httpContext");
            IPrincipal user = filterContext.HttpContext.User;

            bool isFederation = false;
            bool isApp = false;
            IEnumerable<ClaimsIdentity> cl = ((ClaimsPrincipal)User).Identities;
            if (cl != null && cl.Count() > 0)
            {
                foreach (var item in cl)
                {
                    if (item.AuthenticationType.Equals("Federation") && item.IsAuthenticated)
                    {
                        isFederation = true;
                    }
                    else if (item.AuthenticationType.Equals("ApplicationCookie") && item.IsAuthenticated)
                    {
                        isApp = true;
                        if (item.Claims.Where(p => p.Type == "SSO-Login").Count() == 0)
                            isFederation = true;
                    }
                }
            }
            if (!isFederation || !isApp)
                filterContext.Result = new RedirectResult("/Account/Login");

            if (!user.Identity.IsAuthenticated || !AbpSession.UserId.HasValue)
                filterContext.Result = new RedirectResult("/Account/Login");
        }

RP登录:

        public async Task<ActionResult> Login(string userNameOrEmailAddress = "", string returnUrl = "", string successMessage = "")
        {
            bool isFederation = false, isApp = false;
            var identities = ((ClaimsPrincipal)User).Identities;
            if(identities!=null && identities.Count() > 0)
            {
                var federation = identities.Where(p => p.AuthenticationType == "Federation").FirstOrDefault();
                if (federation != null)
                    isFederation = federation.IsAuthenticated;

                var applicationCookie = identities.Where(p => p.AuthenticationType == "ApplicationCookie").FirstOrDefault();
                if (applicationCookie != null)
                    isApp = applicationCookie.IsAuthenticated;
            }
            if (!isFederation)
            {
                FederatedAuthentication.WSFederationAuthenticationModule.SignIn(null);
                return null;
            }
            //创建本地abpsession
            if (!isApp)
            {
                string name = string.Empty, role = string.Empty;
                ClaimsIdentity claims = User.Identity as ClaimsIdentity;
                if (claims != null)
                {
                    var list = claims.Claims.ToList();
                    if (list != null && list.Count > 0)
                    {
                        var cName = claims.Claims.Where(p => p.Type == ClaimTypes.Name).FirstOrDefault();
                        if (cName != null)
                            name = cName.Value;
                        var cRole = claims.Claims.Where(p => p.Type == ClaimTypes.Role).FirstOrDefault();
                        if (cRole != null)
                            role = cRole.Value;

                        var cEmail = claims.Claims.Where(p => p.Type == ClaimTypes.Email).FirstOrDefault();
                        if (cEmail != null)
                            name = cEmail.Value;

                        if (name.Contains("\\"))
                            name = name.Replace("\\", "");
                        if (string.IsNullOrEmpty(role))
                            role = ConfigHelper.GetAppSetting("UserRole");
                    }
                }
                var user = _userIdentity.GetUserByName(name);
                if (user == null)
                {
                    CreateOrUpdateUserInput input = new CreateOrUpdateUserInput();
                    input.User = new UserEditDto();
                    input.User.Name = name;
                    input.User.Surname = input.User.Name;
                    input.User.UserName = input.User.Name;
                    input.User.Password = Infrastructure.Authorization.Users.User.CreateRandomPassword();
                    input.User.EmailAddress = name + "@xx.com";
                    input.AssignedRoleNames = new string[] { role };

                    user = await _userIdentity.CreateUserAsync(input);
                }
                await SignInAsync(user);
            }
            return RedirectToAction("Index", "Home");
        }

RP 登出:

        public ActionResult Logout()
        {
            IEnumerable<ClaimsIdentity> cis = ((ClaimsPrincipal)User).Identities;
            if (cis != null && cis.Count() > 0)
            {
                foreach (var item in cis)
                {
                    if (item.AuthenticationType.Equals("Federation"))
                    {
                        var authModule = FederatedAuthentication.WSFederationAuthenticationModule;
                        WSFederationAuthenticationModule.FederatedSignOut(new Uri(authModule.Issuer + "/Account/Logout"), new Uri(authModule.Reply));
                    }
                    else if (item.AuthenticationType.Equals("ApplicationCookie"))
                    {
                        _authenticationManager.SignOutAll();
                    }
                }
            }
            return RedirectToAction("Login");
        }

 

STS认证成功后回调RP(host:www.test.com)会传入如下信息
将信息.AspNet.ApplicationCookie、FedAuth、FedAuth1复制后使用其它浏览器写入这三个Cookie刷新可正常验证用户信息。
FedAuth、FedAuth1是WIF STS给的认证信息。

技术分享

如果访问的子站点(www.test.com)没有通过STS将认证(FedAuth、FedAuth1)信息回写到子站点的Cookie中,此时使用其它已认证的子站点(FedAuth、FedAuth1)信息模拟到www.test.com站点是无法识别的。

技术分享

WIF认证服务端:

CustomSecurityTokenService.cs

        protected override ClaimsIdentity GetOutputClaimsIdentity(ClaimsPrincipal principal, RequestSecurityToken request, Scope scope)
        {
            //WIF返回Claims中信息,里面了包含自己想要的声明
            ClaimsIdentity outgoingIdentity = new ClaimsIdentity();
            var claims = principal.Claims.ToList();
            foreach(var item in claims)
            {
                if(item.Type != "AspNet.Identity.SecurityStamp" && item.Type != ClaimTypes.NameIdentifier)
                {
                    outgoingIdentity.AddClaim(new Claim(item.Type, item.Value));
                }
            }
            SingleSignOnManager.RegisterRP(scope.AppliesToAddress);
            return outgoingIdentity;
        }

将Claims信息调用RP站管道信息带入到RP站:

        [UnitOfWork]
        public ActionResult Index()
        {
            FederatedPassiveSecurityTokenServiceOperations.ProcessRequest(
                System.Web.HttpContext.Current.Request,
                User as ClaimsPrincipal,
                CustomSecurityTokenServiceConfiguration.Current.CreateSecurityTokenService(),
                System.Web.HttpContext.Current.Response);
            var loginInfo = AsyncHelper.RunSync(() => _sessionAppService.GetCurrentLoginInformations());
            return View(loginInfo);
        }

服务端登录的用户信息。

技术分享

登出只对当前机器当前使用的浏览器生效。实质是浏览器对已访问的子站点遍历wsignoutcleanup1.0。
<img src="@(address)?wa=wsignoutcleanup1.0" style="display:none;" />

 

ABP集成WIF实现单点登录

标签:文件中   setting   刷新   app   ges   href   bsp   iis   out   

原文地址:http://www.cnblogs.com/ddrsql/p/7151777.html

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!