由于采用的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,与公司内部使用的代码与逻辑均不相同,特此声明]