C# 单点登录 MVC
2013-08-17 08:57 通用C#系统架构 阅读(51472) 评论(28) 编辑 收藏 举报跨应用、跨域、跨机器的单点登录。
1、流程:
a) 用户直接访问门户url,登录成功后跳转到默认应用的url。
b) 用户直接访问应用url,若未登录,跳转到登录页面的url,完成登录后,跳转回应用url。
c) 用户已经登录,用户直接访问应用的URL,若该用户无权限,跳转到指定的url
判断是否有url权限的调用方法如下:
[NeedUrlAuthorized] 需要进行Url验证 (首先会要求需要登录)
[HttpPost]
public ActionResult User(Friend.Models.User model)
d) 用户已经登录,用户直接访问用户有权限的应用url,通过。
2、验证码的生成,封装成一个插件,方便各种加强版本的验证需要。
//----------------------------------------------------------------- // All Rights Reserved , Copyright (C) 2013 , Hairihan TECH, Ltd. //----------------------------------------------------------------- using System; using System.Data; using System.Data.Common; using System.Collections.Generic; namespace DotNet.Business { using DotNet.Utilities; /// <summary> /// BaseUserManager /// 用户管理 /// /// 修改纪录 /// /// 2013.08.17 版本:1.0 JiRiGaLa 用户登录后才设置验证码、获取验证码等。 /// /// <author> /// <name>JiRiGaLa</name> /// <date>2011.10.17</date> /// </author> /// </summary> public partial class BaseUserManager : BaseManager { #region public int SetVerificationCode(string userId, string verificationCode) 设置验证码 /// <summary> /// 设置验证码 /// </summary> /// <param name="userId">用户主键</param> /// <param name="verificationCode">验证码</param> /// <returns>影响行数</returns> public int SetVerificationCode(string userId, string verificationCode) { int result = 0; if (string.IsNullOrEmpty(userId) && this.UserInfo != null) { userId = this.UserInfo.Id; } string sqlQuery = string.Empty; sqlQuery = " UPDATE " + BaseUserLogOnEntity.TableName + " SET " + BaseUserLogOnEntity.FieldVerificationCode + " = " + DbHelper.GetParameter("VerificationCode") + " WHERE " + BaseUserLogOnEntity.FieldId + " = " + DbHelper.GetParameter("UserId"); List<IDbDataParameter> dbParameters = new List<IDbDataParameter>(); dbParameters.Add(DbHelper.MakeParameter("VerificationCode", verificationCode)); dbParameters.Add(DbHelper.MakeParameter("UserId", userId)); result = DbHelper.ExecuteNonQuery(sqlQuery, dbParameters.ToArray()); return result; } #endregion #region public bool Verify(string userId, string verificationCode) /// <summary> /// 验证,验证码是否正确 /// </summary> /// <param name="userId">用户主键</param> /// <param name="verificationCode">验证码</param> /// <returns></returns> public bool Verify(string userId, string verificationCode) { bool result = false; string sqlQuery = string.Empty; // 最后一次登录时间 sqlQuery = " SELECT COUNT(1)" + " FROM " + BaseUserLogOnEntity.TableName + " WHERE " + BaseUserLogOnEntity.FieldVerificationCode + " = " + DbHelper.GetParameter("VerificationCode") + " AND " + BaseUserLogOnEntity.FieldId + " = " + DbHelper.GetParameter("UserId"); List<IDbDataParameter> dbParameters = new List<IDbDataParameter>(); dbParameters.Add(DbHelper.MakeParameter("VerificationCode", verificationCode)); dbParameters.Add(DbHelper.MakeParameter("UserId", userId)); object exist = DbHelper.ExecuteScalar(sqlQuery, dbParameters.ToArray()); if (exist != null) { if (BaseSystemInfo.OnLineLimit <= int.Parse(exist.ToString())) { result = true; } } return result; } #endregion } }
3、提供远程访问接口:用户信息的访问;权限信息的访问。访问方式可以是Webservice的方式,封装成一个访问类,方便别人调用。
//----------------------------------------------------------------------- // <copyright file="FriendFansManager.Auto.cs" company="Hairihan"> // Copyright (c) 2013 , All rights reserved. // </copyright> //----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using DotNet.Business; namespace Friend { /// <remarks> /// PermissionWebService /// 权限检查的WebService /// /// 修改纪录 /// /// 2013.08.17 版本:1.0 JiRiGaLa 更新审核意见。 /// /// 版本:1.0 /// /// <author> /// <name>JiRiGaLa</name> /// <date>2013.08.17</date> /// </author> /// </remarks> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class PermissionService : System.Web.Services.WebService { // 如果当前用户没登录后台的权限 DotNet.Business.PermissionService permissionService = new DotNet.Business.PermissionService(); // 如果当前用户登录 // DotNet.Utilities.BaseUserInfo userInfo = Utilities.CheckCookie(HttpContext.Current.Request); public PermissionService() { /* if (userInfo != null && !string.IsNullOrEmpty(userInfo.Code)) { if (!string.IsNullOrEmpty(permissionItemCode)) { bool permissionAdmin = permissionService.IsAuthorizedByUser(userInfo, userInfo.Id, permissionItemCode, string.Empty); if (!permissionAdmin) { throw new Exception("没有权限访问。"); } } } else { throw new Exception("没有权限访问。"); } */ } #region public bool IsUserInRole(string systemCode, string userId, string roleCode) /// <summary> /// 用户是否在某个角色里 /// </summary> /// <param name="systemCode">子系统编号</param> /// <param name="userId">用户主键</param> /// <param name="roleCode">角色编号</param> /// <returns>是否在某个角色里</returns> [WebMethod] public bool IsUserInRole(string systemCode, string userId, string roleCode) { // 需要创建个用户对象 DotNet.Utilities.BaseUserInfo userInfo = new DotNet.Utilities.BaseUserInfo(); // 若没指定是哪个子系统,默认就是基础系统 if (string.IsNullOrEmpty(systemCode)) { systemCode = "Base"; } userInfo.SystemCode = systemCode; // 判断用户是否在指定的角色里? BaseUserManager userManager = new BaseUserManager(userInfo); return userManager.IsInRoleByCode(userId, roleCode); } #endregion #region public bool IsAuthorized(string systemCode, string userId, string permissionItemCode) /// <summary> /// 对某个模块、操作是否有权限? /// </summary> /// <param name="systemCode">子系统编号</param> /// <param name="userId">用户主键</param> /// <param name="permissionItemCode">操作权限编号、模块编号</param> /// <returns>是否拥有操作权限</returns> [WebMethod] public bool IsAuthorized(string systemCode, string userId, string permissionItemCode) { bool returnValue = false; // 需要创建个用户对象 DotNet.Utilities.BaseUserInfo userInfo = new DotNet.Utilities.BaseUserInfo(); // 若没指定是哪个子系统,默认就是基础系统 if (string.IsNullOrEmpty(systemCode)) { systemCode = "Base"; } userInfo.SystemCode = systemCode; // 实时从数据库判断权限的调用方法 returnValue = permissionService.IsAuthorizedByUser(userInfo, userId, permissionItemCode, string.Empty); return returnValue; } #endregion #region public bool IsUrlAuthorized(string systemCode, string userId, string url) /// <summary> /// 对某个模块、操作是否有权限? /// </summary> /// <param name="systemCode">子系统编号</param> /// <param name="userId">用户主键</param> /// <param name="url">按网址授权</param> /// <returns>是否拥有操作权限</returns> [WebMethod] public bool IsUrlAuthorized(string systemCode, string userId, string url) { bool returnValue = false; // 需要创建个用户对象 DotNet.Utilities.BaseUserInfo userInfo = new DotNet.Utilities.BaseUserInfo(); // 若没指定是哪个子系统,默认就是基础系统 if (string.IsNullOrEmpty(systemCode)) { systemCode = "Base"; } userInfo.SystemCode = systemCode; // 实时从数据库判断权限的调用方法 returnValue = permissionService.IsUrlAuthorizedByUser(userInfo, userId, url); return returnValue; } #endregion #region public string[] GetUserPermissions(string systemCode, string userId) /// <summary> /// 获取用户的所有权限列表 /// </summary> /// <param name="systemCode">子系统编号</param> /// <param name="userId">用户主键</param> /// <returns>权限编号数组</returns> [WebMethod] public string[] GetUserPermissions(string systemCode, string userId) { List<string> permissions = new List<string>(); // 需要创建个用户对象 DotNet.Utilities.BaseUserInfo userInfo = new DotNet.Utilities.BaseUserInfo(); // 若没指定是哪个子系统,默认就是基础系统 if (string.IsNullOrEmpty(systemCode)) { systemCode = "Base"; } userInfo.SystemCode = systemCode; // 获取用户的所有权限列表 List<BaseModuleEntity> entityList = permissionService.GetModuleListByUser(userInfo, userId); foreach (var entity in entityList) { // 权限编号 // entity.Code; permissions.Add(entity.Code); // 能访问的url列表 // entity.NavigateUrl; // entity.FullName; } return permissions.ToArray(); } #endregion } }
A: SSO服务器端配置说明:
1: 附加数据库,把sql2008数据库配置好,附加DotNet.CommonV3.9\DotNet.DataBase\SQL2008\UserCenter39
2: 配置 DotNet.Common\Friend, MVC的单点登录程序,配置数据库连接Web.config中的UserCenterDbConnection的数据库连接。
3: 删除单点登录的SSO,SSOVerify,SSOPermissionService项目,从Web.config中。
进行以上3个步骤,mvc 的 SSO 服务器端就配置好了,在iis里设置好MVC网站就可以了。
B: SSO 客户端的配置说明:
1:添加2个dll的引用,DotNet.Business、 DotNet.Utilities,dll在 DotNet.Common\Friend\External 目录下。
2:Controller 需要加 [NeedAuthorize] 进行单点登录控制, [NeedUrlAuthorized]进行ul 权限限制。
3:Web.config 中加 SSO,SSOVerify,SSOPermissionService 的配置。
4:添加 PermissionWebService 引用,就是需要引用 上面里的单点登录 WebService。
5:Global.asax 中需要写一下 Application_Start() 中的代码复制过去。
02:MVC 数据库连接的配置。
03:MVC 用户名密码登录,有错误时需要有错误提示信息。
04:MVC 里保存密码的方式,Cokies 保存测试。
05:MVC cookies 保存的时间长度设置,是否启用cookies。
06:MVC 若有登录自动跳转地址的方式。
07:MVC 用OpenId(Key)登录的方式,登录跳转的优化。
08:MVC 多系统支持单点登录的配置注意事项。
09:MVC 权限判断的例子。
10:MVC URL 权限判断的例子。
11:MVC 退出功能的深入优化,能退出子系统也可以退出主系统。