ASP.NET MVC单点登录(多站点共享用户信息)

一、多站点共享用户信息解决方案:

采用分布式缓存Memcache模拟Session进行用户信息信息共享

1、视图部分

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <title>XX商城后台管理系统登录</title>
    <script type="text/javascript">
        if (window.parent.window != window) {
            window.top.location.href = "/Home/CheckLogin";
        }
    </script>

    <script src="~/Scripts/jquery-1.8.2.min.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    <script type="text/javascript">
        function changeCheckCode() {
            $("#img").attr("src", $("#img").attr("src") + 1);
        }

        function afterLogin(data) {
            if (data=="ok") {
                window.location.href = "/Home/Index";
            }
            else
            {
                $("#errorMsg").text(data);
                changeCheckCode();
            }
        }

    </script>

    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        body {
            text-align: center;
            background: #4974A4;
        }

        #login {
            width: 740px;
            margin: 0 auto;
            font-size: 12px;
        }

        #loginlogo {
            width: 700px;
            height: 100px;
            overflow: hidden;
            background: url(‘/Content/Images/login/logo.png‘) no-repeat;
            margin-top: 50px;
        }

        #loginpanel {
            width: 729px;
            position: relative;
            height: 300px;
        }

        .panel-h {
            width: 729px;
            height: 20px;
            background: url(‘/Content/Images/login/panel-h.gif‘) no-repeat;
            position: absolute;
            top: 0px;
            left: 0px;
            z-index: 3;
        }

        .panel-f {
            width: 729px;
            height: 13px;
            background: url(‘/Content/Images/login/panel-f.gif‘) no-repeat;
            position: absolute;
            bottom: 0px;
            left: 0px;
            z-index: 3;
        }

        .panel-c {
            z-index: 2;
            background: url(‘/Content/Images/login/panel-c.gif‘) repeat-y;
            width: 729px;
            height: 300px;
        }

        .panel-c-l {
            position: absolute;
            left: 60px;
            top: 40px;
        }

        .panel-c-r {
            position: absolute;
            right: 20px;
            top: 50px;
            width: 222px;
            line-height: 200%;
            text-align: left;
        }

        .panel-c-l h3 {
            color: #556A85;
            margin-bottom: 10px;
        }

        .panel-c-l td {
            padding: 7px;
        }

        .login-text {
            height: 24px;
            left: 24px;
            border: 1px solid #e9e9e9;
            background: #f9f9f9;
        }

        .login-text-focus {
            border: 1px solid #E6BF73;
        }

        .login-btn {
            width: 114px;
            height: 29px;
            color: #E9FFFF;
            line-height: 29px;
            background: url(‘/Content/Images/login/login-btn.gif‘) no-repeat;
            border: none;
            overflow: hidden;
            cursor: pointer;
        }

        #txtUsername, #code, #txtPassword {
            width: 191px;
        }

        #logincopyright {
            text-align: center;
            color: White;
            margin-top: 50px;
        }

        a {
            color: Black;
        }

            a:hover {
                color: Red;
                text-decoration: underline;
            }
    </style>

</head>
<body style="padding: 10px">
    <div id="login">
        <div id="loginlogo">
        </div>
        <div id="loginpanel">
            <div class="panel-h">
            </div>
            <div class="panel-c">
                <div class="panel-c-l">
                    @using (Ajax.BeginForm("CheckLogin", new { }, new AjaxOptions() { OnSuccess = "afterLogin" }, new { id = "loginForm" }))
                    {
                        <table cellpadding="0" cellspacing="0">
                            <tbody>
                                <tr>
                                    <td align="left" colspan="2">
                                        <h3>
                                            请使用OA系统账号登录
                                        </h3>
                                    </td>
                                </tr>
                                <tr>
                                    <td align="right">
                                        账号:
                                    </td>
                                    <td align="left">
                                        <input type="text" name="LoginCode" id="LoginCode" class="login-text" />

                                    </td>
                                </tr>
                                <tr>
                                    <td align="right">
                                        密码:
                                    </td>
                                    <td align="left">
                                        <input type="password" name="LoginPwd" id="LoginPwd" value="123" class="login-text" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        验证码:
                                    </td>
                                    <td align="left">
                                        <input type="text" class="login-text" id="code" name="vCode" value="1" />
                                    </td>
                                </tr>
                                <tr>
                                    <td></td>
                                    <td>
                                        <img id="img" src="/Login/ValidateCode/?id=1" style="float: left; height: 24px;" />
                                        <div style="float: left; margin-left: 5px; margin-top: 10px;">
                                            <a href="javascript:void(0)" onclick="changeCheckCode();return false;">看不清,换一张</a>
                                        </div>
                                    </td>
                                </tr>
                                <tr>
                                    <td align="center" colspan="2">
                                        <input type="submit" id="btnLogin" value="登录" class="login-btn" /><a href="/Login/FindPwd">找回密码</a>
                                        <input type="checkbox" name="checkMe" value="1" />记住我
                                        <span id="errorMsg"></span>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    }
                </div>
                <div class="panel-c-r">
                    <p>
                        请从左侧输入登录账号和密码登录
                    </p>
                    <p>
                        如果遇到系统问题,请联系网络管理员。
                    </p>
                    <p>
                        如果没有账号,请联系网站管理员。
                    </p>
                    <p>
                        ......
                    </p>
                </div>
            </div>
            <div class="panel-f">
            </div>
        </div>
        <div id="logincopyright">
            Copyright ? 2012 Yilian.com
        </div>
    </div>
</body>
</html>

登录页面展示:

2、控制器部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApp.Controllers
{
    public class LoginController : Controller
    {
        // GET: /Login/
        CZBK.HeiMaOA.IBLL.IUserInfoService userInfoService { get; set; }

        public ActionResult Index()
        {
            return View();
        }

        #region 用户登录
        public ActionResult CheckLogin()
        {
            string validateCode = Session["validateCode"] == null ? string.Empty : Session["validateCode"].ToString();
            if (string.IsNullOrEmpty(validateCode))
            {
                return Content("验证码错误!");
            }

            //清空防止暴力破解
            Session["validateCode"] = null;

            string requestCode = Request["vCode"];
            if (!requestCode.Equals(validateCode, StringComparison.InvariantCultureIgnoreCase))
            {
                return Content("验证码错误!");
            }
            string userName = Request["LoginCode"];
            string userPwd = Request["LoginPwd"];

            //对用户名、密码进行过滤
            var userInfo = userInfoService.LoadEntities(u => u.UName == userName && u.UPwd == userPwd).FirstOrDefault();
            if (userInfo == null)
            {
                return Content("用户名密码错误!");
            }
            else
            {
                //Session["userInfo"] = userInfo; //普通方式

                #region 利用Memcache模拟Session进行共享用户Session信息
                //自己创建的SessionId,作为Memcache的Key
                string sessionId = Guid.NewGuid().ToString();
                //将用户的信息存储到Memcache中
                CZBK.HeiMaOA.Common.MemcacheHelper.Set(sessionId, CZBK.HeiMaOA.Common.SerializerHelper.SerializerToString(userInfo));
                //然后将自创的SessionId以Cookie的形式返回给浏览器,存储到浏览器端的内存中。
                Response.Cookies["sessionId"].Value = sessionId;
                #endregion

                return Content("ok");
            }
        }
        #endregion

        #region 展示验证码
        public ActionResult ValidateCode()
        {
            CZBK.HeiMaOA.Common.ValidateCode validateCode = new CZBK.HeiMaOA.Common.ValidateCode();
            string code = validateCode.CreateValidateCode(4);
            Session["validateCode"] = code;
            byte[] buffer = validateCode.CreateValidateGraphic(code);
            return File(buffer, "image/jpeg");
        }
        #endregion
    }
}

二、访问页面先验证用户是否登录的解决办法:

1.新建BaseController,让需要验证的继承这个控制器即可:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CZBK.HeiMaOA.Model;

namespace WebApp.Controllers
{
    public class BaseController : Controller
    {
        public UserInfo LoginUser { get; set; }

        /// <summary>
        /// 执行控制器方法之前先执行该方法
        /// 获取自定义SessionId的值,然后从Memcache中取出
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            bool isExt = false;
            if (Request.Cookies["sessionId"] != null)
            {
                //获取自定义的SessionId
                string sessionId = Request.Cookies["sessionId"].Value;
                object obj = CZBK.HeiMaOA.Common.MemcacheHelper.Get(sessionId);
                if (obj != null)
                {
                    LoginUser = CZBK.HeiMaOA.Common.SerializerHelper.DeserializeToObject<UserInfo>(obj.ToString());
                    isExt = true;
                }
            }
            if (!isExt) //用户没登录
            {
                filterContext.HttpContext.Response.Redirect("/Login/Index");
            }
            base.OnActionExecuting(filterContext);
        }

    }
}

2.示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApp.Controllers
{
    public class HomeController : BaseController
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            if (LoginUser != null)
            {
                ViewData["userName"] = LoginUser.UName;
            }
            return View();
        }

    }
}

三、源码下载:

点击下载源码>>

点击下载数据库文件>>

时间: 2024-10-22 17:06:02

ASP.NET MVC单点登录(多站点共享用户信息)的相关文章

Asp.net mvc与PHP的Session共享的实现

最近在做的一个ASP.NET MVC的项目,要用到第三方的php系统,为了实现两个系统的互联互通.决定将两者的session打通共享.让asp.net mvc 和php 都能正常访问和修改Session内容. 在决定实现之前,先搜索了一下院子里有没有相类似的文章,对于跨语言的程序互通,有两种方案: (1)       SSO单点登录,其实就是把用户名和密码传给另一个系统在另一个系统上自动创建session 来解决. (2)       还有就是用同一套Session,在数据库或缓存上架设sess

【CURL】模拟登录网站并获取用户信息

模拟登录网站并获取用户信息 前言 这次来做的是通过代码的方式,模拟登录秒拍官网,获取登录用户的信息. 前后端分离 本文的标题是CURL,传统的网站是PHP代码直接渲染项目视图,通过表单提交到控制器直接进行数据操作. 传统模拟登录的方式在页面上找到表单元素,直接进行模拟表单提交. 近两年前端技术趋于完善,实现了前后端分离. 分析页面元素 秒拍官网地址 http://www.miaopai.com/ 通过审查元素以及源代码查找,在本页面并没有form标签,由此推断页面是通过js进行提交的. 查找提交

MVC - 单点登录中间件 (转)

http://www.cnblogs.com/wangrudong003/p/6435013.html 本章将要和大家分享的是一个单点登录中间件,中间件听起来高深其实这里只是吧单点登录要用到的逻辑和处理流程封装成了几个方法而已,默认支持采用redis服务保存session的方式,也可以使用参数Func<>方法来做自定义session存储操作的方式,就不用我默认提供的redis存储的方法了:要说本章内容的来源,其实是我在以前的ShenNiu.MVC管理系统中加入了最近做的调查问卷模块,这个问卷调

教你开发asp.net的单点登录系统

单点登录系统,简称SSO.以下是我花了几个小时写的一个简单实现.特把实现思路和大家分享. 背景:某项目使用ASP.NET MemberShip来做会员系统,需要同时登录多个系统.而项目的开发人员无法在MemberShip基础上做单点登录. 故这个单点登录系统需要能无缝集成到这些系统中的任何系统中,作为服务端. 下面我们来看看具体的实现步骤,没耐心看完的朋友可直接上github上查阅:(https://github.com/newmin/cms/blob/master/extend/Ops.Cms

asp.net MVC 通用登录验证模块

用法: 还是希望读者把源码看懂,即可运用自如.重点是,为什么有个UserType!!! 登录用户信息: namespace MVCCommonAuth { [Serializable] public class LoginUser { private const string DESKEY = "12345678"; public int ID { get; set; } public string UserName { get; set; } public string Roles

七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理

注:本文为学习摘录,原文地址为:http://www.cnblogs.com/powertoolsteam/p/MVC_five.html 目录 实验22——添加页脚 实验23——实现用户角色管理 实验24——实现项目外观一致性 实验25——使用Action  过滤器让页眉和页脚代码更有效 总结 实验22——添加页脚 在本实验中,我们会在Employee 页面添加页脚,通过本实验理解分部视图. 什么是“分部视图”? 从逻辑上看,分部视图是一种可重用的视图,不会直接显示,包含于其他视图中,作为其视

CAS单点登录之mysql数据库用户验证及常见问题

前面已经介绍了CAS服务器的搭建,详情见:搭建CAS单点登录服务器.然而前面只是简单地介绍了服务器的搭建,其验证方式是原始的配置文件的方式,这显然不能满足日常的需求.下面介绍下通过mysql数据库认证的方式. 一.CAS认证之mysql数据库认证 1.在mysql中新建一个cas数据库并创建user表 CREATE DATABASE /*!32312 IF NOT EXISTS*/`cas` /*!40100 DEFAULT CHARACTER SET gbk */; USE `cas`; /*

如何增加Asp.Net Core生成的模板网站中用户信息表中的列(AspNetUsers)

环境: 1.VS2015 Community 14.0.25431.01 Update 3; 2.其他环境(具体哪一个影响不太清楚,都列在这儿) 使用的系统模板 利用系统提供的模板,并选择个人身份验证.如图: 问题: 模板提供的身份认证数据库中的AspNetUsers表,需要根据需要增加列.以下图为例,绿色框中的列都是模板默认的,我要增加一列(以Test为例). 解决过程: 刚刚接触MVC.EF的概念,不知道如何操作.查阅了大量资料后发现,网上大部分类似内容都是基于mvc3的,最后还是在stac

集成微信第三方登录功能获取微信用户信息

最近公司要做微信的第三方登录,本来打算直接用第三方的框架就算了,就闲的想自己集成试试看. 然后发现被腾讯坑得不省人事. 前提,应用必须要在微信开发平台上注册,并且通过审核,有微信登录的权限. 首先,下载官方的demo.把libs的jar包拷到自己的工程里. 在应用的包名下,建一个wxapi的包目录,在里建一个叫WXEntryActivity的activity并实现IWXAPIEventHandler监听,用于微信回调数据! 下面是我自己的WXEntryActivity,OnUserInfoLis