在一些管理严格的部门需要使用数字证书进行登陆,此时需要专门的数字证书登陆代码才行。
下面就总结一下最近做的一个项目的情况,供大家参考。
一、https 登陆的思路
先不谈网站的https配置问题,另文详细说明。
为了减少网站代码的变化,一般网站都采用了,只有登陆页面使用https,而正常页面还是使用http方式。我的解决办法是这样的:
在iis中配置两个站点,(1)是网站代码,(2)数字证书登陆的代码;用户默认登陆使用数字证书,验证完毕后向 数据库 中 “https”中写入一个随机数(随机生成作为临时验证用的id)、当前时间和一个用户唯一标识(如身份证号),然后自动转移到(1)站点的一个专门的验证页面login_https.aspx,此页面从数据库中“https”查询随机数是否存在,在并且时间相差不超过20秒,则是正常登陆,提取用户的身份证号,到用户信息库中提取相应的登陆信息就可以完成登陆。
代码:
1)数字登陆部分(我用的是usbkey)
- Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
- '-------------------
- Dim CommUrl As String = "1.1.3.4" '此处为站点(1)的ip
- Dim action, Url As String
- Dim Pass As Boolean = False ' 验证通过
- Dim goUrl As String
- Dim IsError As Boolean = False
- If Not Request.ClientCertificate.IsPresent Then
- Throw New Exception("不合法用户禁止访问")
- End If
- Dim SubjectCN As String = Request.ClientCertificate("SubjectCN")
- 'Dim ary As String() = SubjectCN.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
- Dim ary() As string = split(SubjectCN," ")
- If ary.Length <> 2 Then
- Throw New Exception("不合法的证书!")
- end if
- Dim __UserName As String = ary(0).Trim() '用户名
- 'Dim __IDCard As String ' = ary(1).Trim() '身份证号
- Dim sqlstr As String = "select uid,姓名,警号,单位编号,职务编号,Isadmin from 用户 WHERE (身份证号 = '" & ary(1) & "')"
- Dim db As New db
- db.OpenConn()
- Dim Rs As MySqlDataReader
- Rs = db.ExecuteSQL(sqlstr)
- If Not Rs.HasRows Then
- Rs.Close()
- Throw New Exception("未发现您的用户信息")
- Else
- Rs.Close()
- '生成随机字符串用于登陆验证
- Dim ssid As String = getSSID()
- db.ExecuteSQL("insert into https (ssid,time,身份证号) values('" & ssid & "','" & Now() & "','" & ary(1) & "')")
- goUrl = "login_https.aspx?ssid=" & ssid
- End If
- db.CloseConn()
- db = Nothing
- goUrl = "http://" & CommUrl & "/" & goUrl
- '此处必须使用 页面脚本的方式,如果使用直接重定向的话,有出现“转移到不安全站”的提示
- Response.Write("<script>location.href('" & goUrl & "')</script>")
- End Sub
- Private Function getSSID() As String
- '生成一个随机的字符串
- Dim t, i As Int32
- i = 2
- Dim s, pass As String
- s = "abcdefghijklmnopqistuvwsyz1234567890" '~!@#$^&*_+=
- pass = ""
- For i = 1 To 20
- Randomize() '初始化随机数生成器。
- t = Int(Rnd() * Len(s)) + 1
- pass = pass + Mid(s, t, 1)
- Next
- Return pass
- End Function
二、站点(1)处的验证代码login_https.aspx
- Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
- Dim goUrl As String
- Dim ssid As String = Trim(Request.QueryString("ssid"))
- Dim db As New db
- Dim Rs As MySqlDataReader
- db.OpenConn()
- Dim sqlstr As String
- Dim __IDCard As String
- sqlstr = "select 身份证号,time from https WHERE (ssid = '" & ssid & "' order by time desc )"
- Rs = db.ExecuteSQL(sqlstr)
- If Not Rs.HasRows Then
- goUrl = "error.aspx?id=9"
- rs.close()
- Else
- Rs.Read()
- __IDCard = Rs("身份证号")
- Rs.Close()
- '找到接着删除
- sqlstr = "delete from https where ssid='" & ssid & "';"
- sqlstr += "select uid,姓名 from 用户 WHERE (身份证号 = '" & __IDCard & "')"
- If Not Rs.IsClosed Then
- rs.close()
- End If
- Rs = db.ExecuteSQL(sqlstr)
- If Not Rs.HasRows Then
- goUrl = "error.aspx?id=9"
- rs.close()
- Else
- Rs.Read()
- Session.Timeout = 60
- Session("uid") = CStr(Rs(0))
- Session("姓名") = Rs(1)
- rs.close()
- '销毁
- Session.Remove("logintime")
- Session.Remove("num")
- goUrl = "index.aspx"
- End If
- Rs.Close()
- End If
- Response.Redirect(goUrl)
- If Rs.IsClosed Then
- Rs.Close()
- End If
- db.CloseConn()
- db = Nothing
- End Sub