给WSS3.0增加用户与IP绑定功能
公司用WSS3.0做内部协同,但是由于很多分公司在外地,所以协同网站必须在公网上,为了提高安全性和更好的分区域管理,所以要给WSS增加一个用户于IP绑定的功能,这个任务光荣地落到我的头上,结果查遍Google,Baidu无果,只好自力更生。想到的第一个方法是做一个WebPart,在WebPart检测登录的用户名,然后与数据库里的绑定表作对比。不过转念一想WebPart需要部署且要加了的页面才能起作用,整个网站集几十个站点,累也能累死。最后决定自己写一个HttpModule加上去,然后在AuthorizeRequest
事件里来验证。至于验证的过程到是很简单,只需要在数据库里比对一下就行了。
由于采用的Form认证,所以在aspnetdb数据库里增加一个绑定表,就两个列,UserAccount和IpAddr,因为不存在范围之类的所以直接用字符串的形式存储IP。
HttpModule很好写,为了避免每次都读取数据库,在第一次验证成功就生成Cookie,之后检测到Cookie就不再验证了。之前想过用Cache,不过Cache和Application一个级别的,用Session又太麻烦,于是用Cookie,最后代码如下:
不过在Web.Config里加载上这个模块后直接报错了。显示 SqlClientPermission 的权限有问题,看来在这里访问数据库还是有问题,WSS应该对代码的安全性做了限制,查了查Web.Config.看到:
看来是在这里设置的了。找到<trust level="WSS_Custom" originUrl="" /> 发现当前WSS使用的WSS_Custom这个配置,于是就到C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\ 找到Wss_Custom_wss_minimaltrust.config文件
看了下发现里面确实没有关于Sqlclient的配置,本来想就地添加,不过转念一想自己动手怕将来要修改的地方太多太杂,于是继续看了下另外两个config文件,最后在wss_mediumtrust.config 里找到了SqlClint相关的配置,于是最后将trust节点改成<trust level="WSS_Medium" originUrl="" />
打开页面看看,OK,搞定收工。
[本代码乃Demo,与公司内部使用的代码与逻辑均不相同,特此声明]
由于采用的Form认证,所以在aspnetdb数据库里增加一个绑定表,就两个列,UserAccount和IpAddr,因为不存在范围之类的所以直接用字符串的形式存储IP。
HttpModule很好写,为了避免每次都读取数据库,在第一次验证成功就生成Cookie,之后检测到Cookie就不再验证了。之前想过用Cache,不过Cache和Application一个级别的,用Session又太麻烦,于是用Cookie,最后代码如下:
1 public class UserProvider:IHttpModule
2 {
3
4 private HttpApplication ctx;
5 private String User;
6 #region IHttpModule 成员
7
8 public void Dispose()
9 {
10 ctx = null;
11 //throw new Exception("The method or operation is not implemented.");
12 }
13
14 public void Init(HttpApplication context)
15 {
16 ctx = context;
17 context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
18
19 }
20
21 void context_AuthorizeRequest(object sender, EventArgs e)
22 {
23 try
24 {
25 User = ctx.User.Identity.Name.ToLower();
26 if (User != null && User.Length > 1)
27 {
28 if (ctx.Context.Request.Cookies["AuthIP"]== null)
29 {
30 SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
31 string IP = "0.0.0.0";
32 string UIP = "";
33 using (conn)
34 {
35 conn.Open();
36 SqlCommand cmd = new SqlCommand("SELECT [UserAccount],[IPAddr] FROM [aspnetdb].[dbo].[IPLock] WHERE [UserAccount] = @P", conn);
37 cmd.Parameters.Add("@P", SqlDbType.VarChar, 50).Value = User;
38 SqlDataReader sd = cmd.ExecuteReader();
39 if (sd.Read())
40 {
41 IP = sd["IpAddr"].ToString();
42 }
43 conn.Close();
44
45 UIP = ctx.Request.UserHostAddress;
46 if (!IP.Equals("0.0.0.0"))
47 {
48 if (!IP.Equals(UIP))
49 {
50 throw new Exception("IP地址被禁止" + User + ":" + IP);
51 }
52 }
53 ctx.Response.Cookies.Add(new HttpCookie("AuthIP"));
54 ctx.Response.Cookies["AuthIP"].Value = "OK";
55 ctx.Response.Cookies["AuthIP"].Expires = DateTime.Now.AddDays(1);
56 }
57 }
58 }
59 }
60 catch (Exception ex)
61 {
62 throw ex;
63 }
64
65 }
66
67 #endregion
68 }
2 {
3
4 private HttpApplication ctx;
5 private String User;
6 #region IHttpModule 成员
7
8 public void Dispose()
9 {
10 ctx = null;
11 //throw new Exception("The method or operation is not implemented.");
12 }
13
14 public void Init(HttpApplication context)
15 {
16 ctx = context;
17 context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
18
19 }
20
21 void context_AuthorizeRequest(object sender, EventArgs e)
22 {
23 try
24 {
25 User = ctx.User.Identity.Name.ToLower();
26 if (User != null && User.Length > 1)
27 {
28 if (ctx.Context.Request.Cookies["AuthIP"]== null)
29 {
30 SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
31 string IP = "0.0.0.0";
32 string UIP = "";
33 using (conn)
34 {
35 conn.Open();
36 SqlCommand cmd = new SqlCommand("SELECT [UserAccount],[IPAddr] FROM [aspnetdb].[dbo].[IPLock] WHERE [UserAccount] = @P", conn);
37 cmd.Parameters.Add("@P", SqlDbType.VarChar, 50).Value = User;
38 SqlDataReader sd = cmd.ExecuteReader();
39 if (sd.Read())
40 {
41 IP = sd["IpAddr"].ToString();
42 }
43 conn.Close();
44
45 UIP = ctx.Request.UserHostAddress;
46 if (!IP.Equals("0.0.0.0"))
47 {
48 if (!IP.Equals(UIP))
49 {
50 throw new Exception("IP地址被禁止" + User + ":" + IP);
51 }
52 }
53 ctx.Response.Cookies.Add(new HttpCookie("AuthIP"));
54 ctx.Response.Cookies["AuthIP"].Value = "OK";
55 ctx.Response.Cookies["AuthIP"].Expires = DateTime.Now.AddDays(1);
56 }
57 }
58 }
59 }
60 catch (Exception ex)
61 {
62 throw ex;
63 }
64
65 }
66
67 #endregion
68 }
不过在Web.Config里加载上这个模块后直接报错了。显示 SqlClientPermission 的权限有问题,看来在这里访问数据库还是有问题,WSS应该对代码的安全性做了限制,查了查Web.Config.看到:
1 <securityPolicy>
2 <trustLevel name="WSS_Medium" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_mediumtrust.config" />
3 <trustLevel name="WSS_Minimal" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_minimaltrust.config" />
4 <trustLevel name="WSS_Custom" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_custom_wss_minimaltrust.config" />
5 </securityPolicy>
2 <trustLevel name="WSS_Medium" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_mediumtrust.config" />
3 <trustLevel name="WSS_Minimal" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_minimaltrust.config" />
4 <trustLevel name="WSS_Custom" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_custom_wss_minimaltrust.config" />
5 </securityPolicy>
看来是在这里设置的了。找到<trust level="WSS_Custom" originUrl="" /> 发现当前WSS使用的WSS_Custom这个配置,于是就到C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\ 找到Wss_Custom_wss_minimaltrust.config文件
看了下发现里面确实没有关于Sqlclient的配置,本来想就地添加,不过转念一想自己动手怕将来要修改的地方太多太杂,于是继续看了下另外两个config文件,最后在wss_mediumtrust.config 里找到了SqlClint相关的配置,于是最后将trust节点改成<trust level="WSS_Medium" originUrl="" />
打开页面看看,OK,搞定收工。
[本代码乃Demo,与公司内部使用的代码与逻辑均不相同,特此声明]