|
Posted on
2007-05-31 21:55
江南白衣
阅读( 15688)
评论()
收藏
举报
大家都知道,微软企业库中的Security Application Block是把权限规则写在配置文件中的(app.config,web.config),并没有提供存在数据库的实现形式。我去年就向企业库项目组的人建议在SAB中加入这一实现形式,遗憾的是,直到现在的3.1版本,还是没有实现这一功能。
还好GotDotNet上有人提供了这一功能的扩展:Database Rules Provider ,不过这个扩展没有权限操作的功能(添加,删除,修改权限。。。),不方便大家的日常使用,所以我就对其作了一些修改,加入了权限操作功能。现在放出来与大家共享:)
大家都知道,微软企业库中的Security Application Block是把权限规则写在配置文件中的(app.config,web.config),并没有提供存在数据库的实现形式。我去年就向企业库项目组的人建议在SAB中加入这一实现形式,遗憾的是,直到现在的3.1版本,还是没有实现这一功能。 还好GotDotNet上有人提供了这一功能的扩展:Database Rules Provider ,不过这个扩展没有权限操作的功能(添加,删除,修改权限。。。),不方便大家的日常使用,所以我就对其作了一些修改,加入了权限操作功能。现在放出来与大家共享:) 项目下载:Database Authorization Provider.rar DbRulesManager.cs:
1 using System; 2 using System.Data; 3 using System.Data.Common; 4 using System.Data.SqlClient; 5 using System.Configuration; 6 using System.Collections.Generic; 7 using System.Security.Principal; 8 using System.Web.Security; 9![]() 10 using Microsoft.Practices.ObjectBuilder; 11 using Microsoft.Practices.EnterpriseLibrary.Security; 12 //using Microsoft.Practices.EnterpriseLibrary.Security.Authorization; 13 using Microsoft.Practices.EnterpriseLibrary.Security.Configuration; 14 using Microsoft.Practices.EnterpriseLibrary.Data; 15 using Microsoft.Practices.EnterpriseLibrary.Configuration; 16 using System.Configuration.Provider; 17![]() 18 namespace Kreeg.EnterpriseLibrary.Security.Database.Authorization 19![]() ![]() { 20![]() /**//// <summary> 21 /// Class for retrieving rules from the database 22 /// </summary> 23 public class DbRulesManager 24![]() { 25![]() 26 private Microsoft.Practices.EnterpriseLibrary.Data.Database dbRules = null; 27![]() /**//// <summary> 28 /// Creates a Database Rules Manager instance 29 /// </summary> 30 /// <param name="databaseService">The Database Instance to use to query the data(要查询数据的数据库实例)</param> 31 /// <param name="config">The configuration context</param> 32 public DbRulesManager(string databaseService) 33![]() { 34 //DatabaseProviderFactory factory = new DatabaseProviderFactory(config); 35 dbRules = DatabaseFactory.CreateDatabase(databaseService); 36 } 37![]() 38![]() 39![]() /**//// <summary> 40 /// Retrieves a rule from the database 41 /// </summary> 42 /// <param name="Name">The name of the rule</param> 43 /// <returns>An AuthorizationRuleData object</returns> 44 public AuthorizationRuleData GetRule(string name) 45![]() { 46 47 AuthorizationRuleData rule = null; 48![]() 49 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.GetRuleByName"); 50 dbRules.AddInParameter(cmd, "Name", DbType.String, name); 51 52 using(IDataReader reader = dbRules.ExecuteReader(cmd)) 53![]() { 54 if(reader.Read()) 55![]() { 56 rule = GetRuleFromReader(reader); 57 } 58 } 59![]() 60 return rule; 61 } 62![]() 63 private AuthorizationRuleData GetRuleFromReader(IDataReader reader) 64![]() { 65 AuthorizationRuleData rule = new AuthorizationRuleData(); 66 rule.Name = reader.GetString(reader.GetOrdinal("Name")); 67 rule.Expression = reader.GetString(reader.GetOrdinal("Expression")); 68![]() 69 return rule; 70 } 71![]() 72 73![]() /**////// <summary> 74 ///// Retrieves all rules in the database as a DataSet 75 ///// </summary> 76 ///// <returns>A DataSet containing all of the rules</returns> 77 //public DataSet GetAllRules() 78 //{ 79 // DbCommand cmd = dbRules.GetStoredProcCommand("dbo.GetAllRules"); 80![]() 81 // using(DataSet ds = dbRules.ExecuteDataSet(cmd)) 82 // { 83 // return ds; 84 // } 85 //} 86![]() 87![]() 88![]() /**//// <summary> 89 /// Retrieves all rules in the database as a Collection 90 /// </summary> 91 /// <returns>An AuthorizationRuleDataCollection containing all of the rules</returns> 92 public List<AuthorizationRuleData> GetAllRulesAsCollection() 93![]() { 94 List<AuthorizationRuleData> rules = new List<AuthorizationRuleData>(); 95![]() 96 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.GetAllRules"); 97 98 using(IDataReader reader = dbRules.ExecuteReader(cmd)) 99![]() { 100 while(reader.Read()) 101![]() { 102 AuthorizationRuleData rule = GetRuleFromReader(reader); 103 rules.Add(rule); 104 } 105 } 106 return rules; 107 } 108![]() 109![]() /**//// <summary> 110 /// Inserts a rule into the database 111 /// </summary> 112 /// <param name="name">The name of the rule</param> 113 /// <param name="expression">The expression defining the rule</param> 114 public void InsertRule(string name, string expression,string description) 115![]() { 116 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.InsertRule"); 117 dbRules.AddInParameter(cmd, "Name", DbType.String, name); 118 dbRules.AddInParameter(cmd, "Expression", DbType.String, expression); 119 dbRules.AddInParameter(cmd, "Description",DbType.String, description); 120![]() 121 dbRules.ExecuteNonQuery(cmd); 122 } 123![]() 124![]() /**//// <summary> 125 /// Saves the rule to the database 126 /// </summary> 127 /// <param name="ruleId">The Rule Id</param> 128 /// <param name="name">The name of the rule</param> 129 /// <param name="expression">The expression</param> 130 public void UpdateRuleById(int ruleId, string name, string expression) 131![]() { 132 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.UpdateRuleById"); 133 dbRules.AddInParameter(cmd, "id", DbType.Int32, ruleId); 134 dbRules.AddInParameter(cmd, "Name", DbType.String, name); 135 dbRules.AddInParameter(cmd, "Expression", DbType.String, expression); 136 //dbRules.AddInParameter(cmd, "Description", DbType.String, description); 137![]() 138 dbRules.ExecuteNonQuery(cmd); 139 } 140![]() 141![]() /**//// <summary> 142 /// Removes a rule from the database 143 /// </summary> 144 /// <param name="ruleId">The ruleid to remove</param> 145 public void DeleteRuleById(int ruleId) 146![]() { 147 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.DeleteRuleById"); 148 dbRules.AddInParameter(cmd, "id", DbType.Int32, ruleId); 149![]() 150 dbRules.ExecuteNonQuery(cmd); 151 } 152![]() 153![]() 154![]() /**//***************** Follow Function Created by levinknight 2006.06.07 *****************/ 155![]() 156![]() GetAllRules#region GetAllRules 157 public string[] GetAllRules() 158![]() { 159 string rules = string.Empty; 160 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.GetAllRules"); 161![]() 162 using (DataSet ds = dbRules.ExecuteDataSet(cmd)) 163![]() { 164 foreach (DataRow rule in ds.Tables[0].Rows) 165![]() { 166 rules += (string)rule["Name"] + ","; 167 } 168![]() 169 if (rules.Length >0) 170![]() { 171 rules = rules.Substring(0,rules.Length -1); 172 return rules.Split(','); 173 } 174![]() 175 return new string[0]; 176 } 177 } 178 #endregion 179![]() 180![]() GetRulesForUser by IPrincipal#region GetRulesForUser by IPrincipal 181 public string[] GetRulesForUser(IPrincipal principal) 182![]() { 183 if (principal == null) 184![]() { 185 throw new ArgumentException("Principal cannot be null."); 186 } 187![]() 188 return GetEffectiveRules(principal); 189 } 190 #endregion 191![]() 192![]() GetRulesForuser by Username#region GetRulesForuser by Username 193 public string[] GetRulesForUser(string username) 194![]() { 195 string[] roles = Roles.GetRolesForUser(username); 196 IPrincipal principal = new GenericPrincipal(new GenericIdentity(username),roles); 197![]() 198 return GetEffectiveRules(principal); 199 } 200 #endregion 201![]() 202![]() GetRulesForRole by Role'Name#region GetRulesForRole by Role'Name 203 public string[] GetRulesForRole(string rolename) 204![]() { 205![]() string[] roles = new string[1] {rolename}; 206 IPrincipal principal = new GenericPrincipal(new GenericIdentity(""), roles); 207![]() 208 return GetEffectiveRules(principal); 209 } 210 #endregion 211![]() 212![]() GetEffectiveRules Service for GetRulesFor User or Role#region GetEffectiveRules Service for GetRulesFor User or Role 213 private string[] GetEffectiveRules(System.Security.Principal.IPrincipal principal) 214![]() { 215 string rules = ""; 216 List<AuthorizationRuleData> ruleCollection = GetAllRulesAsCollection(); 217![]() 218 try 219![]() { 220 foreach (AuthorizationRuleData rule in ruleCollection) 221![]() { 222 if ( IsInRule(principal,rule.Expression) ) 223![]() { 224 rules += rule.Name + ","; 225 } 226 } 227 } 228 catch (SyntaxException) 229![]() { 230 throw new ProviderException("返回有效权限时发生了错误,权限表达式非法"); 231 } 232![]() 233 if (rules.Length > 0) 234![]() { 235 //删除最末尾的逗号 236 rules = rules.Substring(0,rules.Length - 1); 237 return rules.Split(','); 238 } 239![]() 240 return new string[0]; 241 } 242 #endregion 243![]() 244![]() AddUserToRule#region AddUserToRule 245![]() 246 public void AddUserToRule(string ruleName,string username) 247![]() { 248 if (ruleName.Length == 0 || username.Length == 0) 249![]() { 250 throw new ProviderException("权限名和用户名都不能为空"); 251 } 252 253 string[] roles = Roles.GetRolesForUser(username); 254 IPrincipal principal = new GenericPrincipal(new GenericIdentity(username), roles); 255![]() 256 AuthorizationRuleData rule = GetRule(ruleName); 257![]() 258 if (rule == null) 259![]() { 260 throw new ProviderException(string.Format("权限: '{0}'不在数据库中",ruleName)); 261 } 262![]() 263 264 if ( IsInRule(principal,rule.Expression) ) 265![]() { 266 throw new ProviderException(string.Format("用户: '{0}'已经拥有权限: '{1}'",username,ruleName)); 267 } 268![]() 269 string ruleExpression = string.Empty; 270 string tempExpression = string.Empty; 271![]() 272 if (rule.Expression.Contains(string.Format(" AND (NOT I:{0})", username))) 273![]() { 274 tempExpression = ruleExpression = rule.Expression.Replace(string.Format(" AND (NOT I:{0})", username), ""); 275 if (IsInRule(principal, tempExpression)) 276![]() { 277 ruleExpression = rule.Expression.Replace(string.Format(" AND (NOT I:{0})", username), ""); 278 } 279 else 280![]() { 281 ruleExpression = rule.Expression.Replace(string.Format(" AND (NOT I:{0})", username), 282 string.Format(" OR (I:{0})", username) 283 ); 284 } 285 } 286 else if (rule.Expression.Contains(string.Format("(NOT I:{0})", username))) 287![]() { 288 ruleExpression = rule.Expression.Replace(string.Format("(NOT I:{0})", username), 289 string.Format("(I:{0})", username) 290 ); 291 } 292 else 293![]() { 294 ruleExpression = rule.Expression + string.Format(" OR (I:{0})", username); 295 } 296![]() 297 try 298![]() { 299 new Parser().Parse(ruleExpression); 300 } 301 catch (SyntaxException) 302![]() { 303 throw; 304 } 305![]() 306 UpdateRuleByName(rule.Name,ruleExpression); 307 } 308 309 #endregion 310![]() 311![]() RemoveUserFromRule#region RemoveUserFromRule 312 public void RemoveUserFromRule(string ruleName, string username) 313![]() { 314 if (ruleName.Length == 0 || username.Length == 0) 315![]() { 316 throw new ProviderException("权限名和用户名都不能为空"); 317 } 318 319 string[] roles = Roles.GetRolesForUser(username); 320 IPrincipal principal = new GenericPrincipal(new GenericIdentity(username), roles); 321![]() 322 Parser parser = new Parser(); 323 AuthorizationRuleData rule = GetRule(ruleName); 324![]() 325 if ( !parser.Parse(rule.Expression).Evaluate(principal) ) 326![]() { 327 throw new ProviderException(string.Format("用户: '{0}'已经没有权限: '{1}'", username,ruleName)); 328 } 329![]() 330 string ruleExpression; 331 332 //此用户已经拥有了此权限 333 if (rule.Expression.Contains(string.Format(" OR (I:{0})", username))) 334![]() { 335 ruleExpression = rule.Expression.Replace(string.Format(" OR (I:{0})", username), ""); 336 } 337 //后面有表达式 OR![]() 338 else if (rule.Expression.Contains(string.Format("(I:{0}) OR ", username))) 339![]() { 340 ruleExpression = rule.Expression.Replace(string.Format("(I:{0}) OR ", username), ""); 341![]() 342 } 343 //后面有表达式 AND![]() 344 else if (rule.Expression.Contains(string.Format("(I:{0}) AND ", username))) 345![]() { 346 ruleExpression = rule.Expression.Replace(string.Format("(I:{0}) AND ", username), ""); 347 } 348 //只有此用户拥有此权限 349 else if (rule.Expression.Contains(string.Format("(I:{0})", username))) 350![]() { 351 //ruleExpression = rule.Expression.Replace(string.Format("(I:{0})", username), ""); 352 throw new ProviderException("权限必须属于至少一个角色或用户!!!"); 353 } 354 //只是此用户所属的角色拥有此权限 355 else 356![]() { 357 ruleExpression = rule.Expression + string.Format(" AND (NOT I:{0})", username); 358 } 359![]() 360 UpdateRuleByName(ruleName,ruleExpression); 361 } 362 #endregion 363![]() 364![]() AddRoleToRule#region AddRoleToRule 365 public void AddRoleToRule(string ruleName,string roleName) 366![]() { 367 if (ruleName.Length == 0 || roleName.Length ==0) 368![]() { 369 throw new ProviderException("权限名和角色名都不能为空"); 370 } 371 372![]() string[] roles = new string[1] {roleName}; 373 IPrincipal principal = new GenericPrincipal( new GenericIdentity(""),roles ); 374![]() 375 Parser parser = new Parser(); 376 AuthorizationRuleData rule = GetRule(ruleName); 377 BooleanExpression parsedExpression; 378![]() 379 if (rule == null) 380![]() { 381 throw new ProviderException(string.Format("权限: '{0}'不在数据库中", ruleName)); 382 } 383![]() 384 parsedExpression = parser.Parse(rule.Expression); 385 if (parsedExpression.Evaluate(principal)) 386![]() { 387 throw new ProviderException(string.Format("角色: '{0}'已经拥有权限: '{1}'", roleName, ruleName)); 388 } 389![]() 390 string ruleExpression = string.Empty; 391![]() 392 if (rule.Expression.Contains(string.Format(" AND (NOT R:{0})", roleName))) 393![]() { 394 ruleExpression = rule.Expression.Replace(string.Format(" AND (NOT R:{0})", roleName), 395 string.Format(" OR (R:{0})", roleName) 396 ); 397 } 398 else 399![]() { 400 ruleExpression = rule.Expression + string.Format(" OR (R:{0})", roleName); 401 } 402![]() 403 ruleExpression = rule.Expression + string.Format(" OR (R:{0})", roleName); 404![]() 405 try 406![]() { 407 parser.Parse(ruleExpression); 408 } 409 catch (SyntaxException)//权限表达式非法 410![]() { 411 throw new ApplicationException("权限表达式非法"); 412 } 413![]() 414 UpdateRuleByName(rule.Name, ruleExpression); 415![]() 416 } 417 #endregion 418![]() 419![]() RemoveRoleFromRule#region RemoveRoleFromRule 420 public void RemoveRoleFromRule(string ruleName,string roleName) 421![]() { 422 string[] roles; 423![]() roles = new string[1] { roleName }; 424![]() 425 if (ruleName.Length == 0 || roleName.Length == 0) 426![]() { 427 throw new ProviderException("权限名和角色名都不能为空"); 428 } 429 430 IPrincipal principal; 431 principal= new GenericPrincipal(new GenericIdentity(""), roles); 432![]() 433 Parser parser = new Parser(); 434 AuthorizationRuleData rule = GetRule(ruleName); 435![]() 436 if (!parser.Parse(rule.Expression).Evaluate(principal)) 437![]() { 438 throw new ProviderException(string.Format("角色: '{0}'已经没有权限: '{1}'", roleName, ruleName)); 439 } 440![]() 441 string ruleExpression = string.Empty; 442 int i = 0; 443![]() 444 //计算有几个角色拥有此权限 445 foreach (string role in Roles.GetAllRoles()) 446![]() { 447 roles[0] = role; 448 principal = new GenericPrincipal(new GenericIdentity(""),roles); 449![]() 450 if (parser.Parse(rule.Expression).Evaluate(principal)) 451![]() { 452 i++; 453 } 454 } 455![]() 456 if (i < 2) 457![]() { 458 throw new ProviderException("每个权限至少要属于一个角色!"); 459 } 460 461 462 //此角色已经拥有了此权限 463 if (rule.Expression.Contains(string.Format(" OR (R:{0})", roleName))) 464![]() { 465 ruleExpression = rule.Expression.Replace(string.Format(" OR (R:{0})", roleName), ""); 466 } 467 //后面有表达式 OR![]() 468 else if (rule.Expression.Contains(string.Format("(R:{0}) OR ", roleName))) 469![]() { 470 ruleExpression = rule.Expression.Replace(string.Format("(R:{0}) OR ", roleName), ""); 471![]() 472 } 473 //后面有表达式 AND![]() 474 else if (rule.Expression.Contains(string.Format("(R:{0}) AND ", roleName))) 475![]() { 476 ruleExpression = rule.Expression.Replace(string.Format("(R:{0}) AND ", roleName), ""); 477 } 478 //只有此角色拥有此权限 479 //else if (rule.Expression.Contains(string.Format("(R:{0})", roleName))) 480 //{ 481 // //ruleExpression = rule.Expression.Replace(string.Format("(I:{0})", username), ""); 482 // throw new ProviderException("权限必须属于至少一个角色或用户!!!"); 483 //} 484![]() /**/////只是此角色拥有此权限 485 //else 486 //{ 487 // ruleExpression = rule.Expression + string.Format(" AND (NOT I:{0})", roleName); 488 //} 489![]() 490 UpdateRuleByName(ruleName, ruleExpression); 491 } 492 #endregion 493![]() 494![]() UpdateRuleByName#region UpdateRuleByName 495 private void UpdateRuleByName(string ruleName,string ruleExpression) 496![]() { 497 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.UpdateRuleByName"); 498 dbRules.AddInParameter(cmd, "Name", DbType.String, ruleName); 499 dbRules.AddInParameter(cmd, "Expression", DbType.String, ruleExpression); 500![]() 501 dbRules.ExecuteNonQuery(cmd); 502 } 503 #endregion 504![]() 505![]() DeleteRuleByName#region DeleteRuleByName 506 public void DeleteRuleByName(string ruleName) 507![]() { 508 if (ruleName.Length == 0) 509![]() { 510 throw new ProviderException("要删除的权限名不能为空"); 511 } 512 513 DbCommand cmd = dbRules.GetStoredProcCommand("dbo.DeleteRuleByName"); 514 dbRules.AddInParameter(cmd, "Name", DbType.String, ruleName); 515![]() 516 dbRules.ExecuteNonQuery(cmd); 517 } 518 #endregion 519![]() 520![]() CreateRule#region CreateRule 521 public void CreateRule(string ruleName,string description,string[] roles) 522![]() { 523 string ruleExpression; 524 string roleRules = string.Empty; 525 //string userRules = string.Empty; 526 527 if (ruleName == null) 528![]() { 529 throw new ArgumentException("权限名不能为空"); 530 } 531![]() 532 if (roles.Length == 0) 533![]() { 534 throw new ProviderException("创建权限时必须指明权限的所属角色"); 535 } 536![]() 537 if (roles.Length > 0) 538![]() { 539 foreach (string role in roles) 540![]() { 541 roleRules += string.Format("(R:{0}) OR ",role); 542 } 543 544 if (roles.Rank > 0) 545![]() { 546 roleRules = roleRules.Substring(0, roleRules.Length - 4); 547 } 548 } 549![]() 550 ruleExpression = roleRules; 551![]() 552 try 553![]() { 554 new Parser().Parse(ruleExpression); 555 } 556 catch (SyntaxErrorException) 557![]() { 558 throw; 559 } 560 561 InsertRule(ruleName,ruleExpression,description); 562 } 563 #endregion 564![]() 565![]() IsInRule#region IsInRule 566 private bool IsInRule(IPrincipal principal,string ruleExpression) 567![]() { 568 Parser parser = new Parser(); 569 BooleanExpression parsedExpression; 570![]() 571 try 572![]() { 573 parsedExpression = parser.Parse(ruleExpression); 574 } 575 catch (SyntaxException) 576![]() { 577 throw; 578 } 579![]() 580 if (parsedExpression.Evaluate(principal)) 581![]() { 582 return true; 583 } 584![]() 585 return false; 586 } 587 #endregion 588 } 589 } 590![]()
|