tiida2011 2012-6-23 15:07 本案例是为一个中型规模的外包软件公司开发的WiFi网页认证系统。
整个公司的网络都是采用典型的Windows活动目录(Active Directory)进行管理,所有员工都分配有各自的域账户。员工的计算机都是有线连接,因为主要做的是外包项目,信息安全方面要求很严格,所以公司规定一般的员工不能上网。
现在公司希望在每一层都能为员工提供无线WiFi上网的方式(非办公用),但是也需要用域账户进行认证,而且要用Web认证(可以防止WiFi万能钥匙这类手机软件)。
我们采用的方式非常简单,即,在每一层都安装一个无线路由器,WAN口接入公司网络(非办公用网段)并连接外网。无线路由器统一刷DD-WRT,安装Wiwiz客户端。
然后在公司内网的Java服务器中增加一个我们写的JSP页面,用于Web认证。
重点就在这个JSP页面程序,这里简要说明一下。
这个JSP页面程序接收来自无线网络用户提交的域名、用户名和密码,然后连接域控制器,进行域账户的验证,如果出错则报错。如果域账户验证通过,则调用Wiwiz Auth API使之完成Web认证。认证通过后,浏览器将自动显示公司内网主页。
简易版的效果图如下:
以下是Web认证页面的JSP程序源码: %@ page contentType= text/html;charset=UTF-8 % %@ page import= java.io.* % %@ page import= java.util.* % %@ page import= java.net.* % %@ page import= javax.naming.* % %@ page import= javax.naming.directory.* % %String userkey = XXXXXXXXXXXXXXXX // 替换为你的User KeyString host = XXX.XXX.XXX.XXX // AD服务器地址String port = 389 // AD服务器端口String hrsys = http://hrsys // 公司内网系统首页地址,用于认证后显示//****************************************************// 取得接收到的传入参数//**************************************************** String pTokencode = request.getParameter( tokencode // 接收到的传入参数 tokencode String pSrvurl = request.getParameter( srvurl // 接收到的传入参数 srvurl /* 如必要,把传入参数存放于Session对象中 */if(pTokencode != null) session.setAttribute( tokencode , pTokencode);if(pSrvurl != null) session.setAttribute( srvurl , pSrvurl);% html head meta http-equiv= Content-Type content= text/html; charset=UTF-8 meta http-equiv= Content-Language content= zh meta http-equiv= Pragma content= no-cache meta http-equiv= Cache-Control content= no-cache title 用户认证 /title /head body center br form action= method= post b 请使用公司的域账户进行认证 /b br br table bgcolor= #eefffff border= 0 cellspacing= 1 cellpadding= 6 width= 350 tr td align= right Domain: /td td input type= text name= domain value= %=request.getParameter( domain ) == null ? : request.getParameter( domain )% / /td /tr tr td align= right 用户名: /td td input type= text name= username value= %=request.getParameter( username ) == null ? : request.getParameter( username )% / /td /tr tr td align= right 密码: /td td input type= password name= pswd / /td /tr /table br input type= submit name= login value= 登录 quot;history.back(); /form %if(request.getParameter( login ) != null) { /* “登录”按钮按下时 */% table width= 260 bgcolor= #888888 border= 0 cellspacing= 1 cellpadding= 8 tr td bgcolor= #ffff99 align= center valign= middle b % //**************************************************** // 第1步. 根据您的具体需要或业务,进行用户登录验证处理 //**************************************************** boolean loginSuccess = true; String username = request.getParameter( username // 用户名 String pswd = request.getParameter( pswd // 密码 String domain = request.getParameter( domain // Domain /* 进行输入参数的校验 */ if(username.equals( )) { out.print( 用户名不可为空! br loginSuccess = false; } if(pswd.equals( )) { out.print( 密码不可为空! br loginSuccess = false; } if(domain.equals( )) { out.print( Domain不可为空! br loginSuccess = false; } /* 域账户验证 */ if(loginSuccess == true) { String url = new String( ldap:// + host + : + port); String user = username.indexOf(domain) 0 ? username : username + @ + domain; Hashtable String, String env = new Hashtable String, String DirContext ctx; env.put(Context.SECURITY_AUTHENTICATION, simple env.put(Context.SECURITY_PRINCIPAL, user); env.put(Context.SECURITY_CREDENTIALS, pswd); env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.ldap.LdapCtxFactory env.put(Context.PROVIDER_URL, url); try { ctx = new InitialDirContext(env); ctx.close(); loginSuccess = true; } catch (NamingException e) { //e.printStackTrace(); loginSuccess = false; out.print( 登录失败! // } }% br /b /td /tr /table % if(loginSuccess == true) { //**************************************************** // 第2步. 调用Wiwiz Auth API,进行预认证 // 重要: 请在服务器端的程序中进行此处理(例如,ASP、C#、JSP/Servet、PHP…), // 而不要在直接客户端代码中进行此处理(例如,HTML/Javascript) //**************************************************** // 参数 action : 必须! // 设置为 1 将使用户认证成功 // 设置为 1 将使用户认证失败 String action = 1 // 参数 tokencode : 必须! // 设置与同名传入参数相同的值 String tokencode = (String) session.getAttribute( tokencode // 参数 srvurl : 必须! // 设置与同名传入参数相同的值 String srvurl = (String) session.getAttribute( srvurl // 参数 endtime : 可选 // 格式: yyyy-mm-dd hh:MM:ss例如: 2012-05-31 21:39:00 // 设置此参数将使用户的Internet连接在指定时间关闭 // 注意: 对此参数的值必须进行url编码 String endtime = //URLEncoder.encode( 2012-05-31 21:39:00 , utf-8 // 参数 postauth : 可选 // 例如: http://www.YourDomain.com // 设置此参数将设置用户在通过认证后显示的页面地址 String postauth = hrsys; String parameters = wiwiz_auth_api=1 ver=1.0 + // 参数 wiwiz_auth_api 与 ver . 固定值 tokencode= + tokencode + // 参数 tokencode . 设置方法参考上面的说明 userkey= + userkey + // 参数 userkey . 设置方法参考上面的说明 action= + action + // 参数 action . 设置方法参考上面的说明 endtime= + endtime + // 参数 endtime . 设置方法参考上面的说明 postauth= + postauth; // 参数 postauth . 设置方法参考上面的说明 URL u = new URL(srvurl); // 使用传入参数 srvurl 的值作为请求地址 URLConnection uc = u.openConnection(); uc.setDoOutput(true); uc.setRequestProperty( Content-Type , application/x-www-form-urlencoded PrintWriter pw = new PrintWriter(uc.getOutputStream()); pw.println(parameters); pw.close(); BufferedReader in = new BufferedReader( new InputStreamReader(uc.getInputStream())); String verifycode = in.readLine(); in.close(); if(verifycode.startsWith( ERR )) { // 如果报错,则显示错误代码 out.println( Error: + verifycode); } else { // 如没有报错则进行第3步。 //**************************************************** // 第3步. 调用Wiwiz Auth API,完成认证 //**************************************************** String redirectUrl = srvurl + // 使用传入参数 srvurl 的值作为跳转地址的前缀 ?wiwiz_auth_api_login=1 + // 参数 wiwiz_auth_api_login ,固定值 tokencode= + tokencode + // 参数 tokencode ,设置与同名传入参数相同的值 verifycode= + verifycode; // 参数 verifycode ,设置与同名传入参数相同的值 response.sendRedirect(redirectUrl); // 最后,进行跳转 } }}% /center /body /html 复制代码
服务热线
130-6262-9899