• 关于web应用程序的安全验证


    通常对于一般的web应用程序,都是自己写验证,输入用户名和密码,然后到数据库去验证,然后返回。但是对于安全性要求较高的应用,自己写的安全验证则会出现许多没考虑到的地方,这时应该使用安全框架。
            我使用的是struts框架,服务器是weblogic8.14,配置了基于FORM的验证方式,具体配置如下:
            1、目录结构:根目录文件:index.jsp,login.html,error.jsp
                                      admin目录:存放系统模块业务页面的路径
                                      pages目录:存放公用页面的路径
             2、login.html:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[url]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]">
    <html xmlns="[url]http://www.w3.org/1999/xhtml[/url]">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style type="text/css">
    body{
     margin:0;
     font-size:12px;
     height:100%;
    }
    #content {
     position:absolute;
     left:58%;
     top:42%;
     190px;
     height:104px;
     z-index:1;
    }
    .int{
     120px;
     height:13px;
     border:#c0c0c0 1px solid;
    }
    .btn{padding-top:2px;}
    </style>
    </head>
    <body>
    <div id="content">
      <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <form  method="post" action="j_security_check">
     <tr>
       <td height="25" colspan="2" align="right" valign="bottom">&nbsp;</td>
       </tr>
     <tr>
          <td width="60" height="35" align="right" valign="bottom">用户id:</td>
          <td width="120" valign="bottom"><input type="text" name="j_username"  id="j_username" class="int"/></td>
        </tr>
        <tr>
          <td width="60" height="25" align="right" valign="bottom">密码:</td>
          <td valign="bottom"><input type="password" name="j_password" id="j_password" class="int"/></td>
        </tr>
        <tr>
          <td colspan="2">&nbsp;</td>
        </tr>
        <tr>
          <td height="30" colspan="2" align="right">
            <input type="submit"  id="btnok" value="登录" class="btn"/>
           <input id="reset" type="reset" value="取消" class="btn"/></td>
        </tr>
        </form>
      </table>
    </div>
    <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
      <tr>
        <td><table width="601" height="364" border="0" align="center" cellpadding="0" cellspacing="0" background=\'#\'" /login.jpg">
          <tr>
            <td>&nbsp;</td>
          </tr>
        </table></td>
      </tr>
    </table>
    </body>
    </html>
     
     需要注意的是这里的用户名,密码和提交页面必须固定为j_username,j_password,j_security_check见文件的反显部分。
     
    3、error.jsp
    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title>
    error
    </title>
    </head>
    <body bgcolor="#ffffff">
    <h1>
    Login error!
    </h1>
    </body>
    </html>
    4、在web.xml里配置要保护的资源
    <security-constraint>
        <web-resource-collection>
          <web-resource-name>admin</web-resource-name>
          <url-pattern>/admin/*</url-pattern>
          <http-method>PUT</http-method>
          <http-method>GET</http-method>
        </web-resource-collection>
        <web-resource-collection>
          <web-resource-name>pages</web-resource-name>
          <url-pattern>/pages/*</url-pattern>
          <http-method>PUT</http-method>
          <http-method>GET</http-method>
        </web-resource-collection>
        <web-resource-collection>
          <web-resource-name>indexservlet</web-resource-name>
          <url-pattern>/indexservlet</url-pattern>
          <http-method>PUT</http-method>
          <http-method>GET</http-method>
        </web-resource-collection>
        <web-resource-collection>
          <web-resource-name>index</web-resource-name>
          <url-pattern>/index.jsp</url-pattern>
          <http-method>PUT</http-method>
          <http-method>GET</http-method>
        </web-resource-collection>
        <auth-constraint>
          <role-name>mgr</role-name>
        </auth-constraint>
        <user-data-constraint>
          <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
      </security-constraint>
    这里我配置了对admin目录、index.jsp、indexservlet的保护,只允许mgr角色可以访问,注意不要对error.jsp也保护了,否则会导致登陆失败时达不到错误页面。
     
    5、配置角色:
    mgr是这样配置的:
    在web.xml里加入:
    <security-role>
        <role-name>mgr</role-name>
      </security-role>
     
    在weblogic.xml里加入角色映射:
    <security-role-assignment>
        <role-name>mgr</role-name>
        <principal-name>admin</principal-name>
          </security-role-assignment>
    该段表示将weblogic服务器里配置的admin用户映射为这里的mgr角色。
     
    6、配置验证方式:
    在web.xml里加入
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
          <form-login-page>/login.html</form-login-page>
          <form-error-page>/error.jsp</form-error-page>
        </form-login-config>
      </login-config>
     
    现在,打包发布你的程序,输入任何保护的资源,在未验证的情况下就会跳转到登陆页面了,从而完成对资源的保护。
     

    Web应用程序登录后的处理

    上次说了利用服务器进行登录的安全验证,在进行安全的服务器验证后,进入被保护的资源,例如welcome页面,现在的问题是,如果欢迎页面要求作一些数据操作,例如动态菜单等,可是我们登录提交的是j_security_check,这是系统自身完成的,应该如何完成这些工作呢?我采用的方法是将welcome-file指定为一个servlet,如下:
    <welcome-file-list>
        <welcome-file>/indexservlet</welcome-file>
      </welcome-file-list>
     
    IndexServlet如下:
    public class IndexServlet extends HttpServlet {
        private static final String CONTENT_TYPE = "text/html; charset=UTF-8";
        //Initialize global variables
        public void init() throws ServletException {
        }
        //Process the HTTP Get request
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws
                ServletException, IOException {
            response.setContentType(CONTENT_TYPE);
            if (request.getUserPrincipal() != null) {
                String userid = request.getUserPrincipal().getName();
                IndexOperImpl oper = new IndexOperImpl();
                Class cls = oper.getClass();
                InvocationHandler ds = new OperProxy(oper);
                IndexOperInterface operi = (IndexOperInterface) Proxy.
                                           newProxyInstance(cls.getClassLoader(),
                        cls.getInterfaces(), ds);
                UserQuery userquery = new UserQuery();
                userquery.setUser_id(userid);
                User user1 = operi.getUserInfo(userquery);
                MenuItemList menulist = operi.getMenuItemList(user1);
                WorkItemList worklist = operi.getWorkItemList(user1);
                if (user1 != null) {
                    request.getSession().setAttribute("userid", user1.getUser_id());
                    request.getSession().setAttribute("username",
                                                      user1.getUser_name());
                    request.getSession().setAttribute("department",
                                                      user1.getUser_department());
                }
                if (menulist != null) {
                    request.getSession().setAttribute("menulistbean",
                                                      menulist.getMenulist());
                }
                if (worklist != null) {
                    request.getSession().setAttribute("worklistbean",
                                                      worklist.getWorkItemList());
                }
                response.sendRedirect(response.encodeRedirectURL("/index.jsp"));
            }
        }
        //Process the HTTP Post request
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws
                ServletException, IOException {
            doGet(request, response);
        }
        //Clean up resources
        public void destroy() {
        }
    }
     
    如上描述,request.getUserPrincipal().getName();方法获得登录后的用户编号,黄底色的是代理实现,这里的代理对象叫operi,使用getUserInfo(UserQuery userquery)方法从后台获取用户信息,getUserInfo是前后台接口方法UserQuery 是前后台数据传输的DTO.同样,workItemList和MenuItemList都是DTO,而getWorkItemList和getMenuItemList则是接口方法。将获得的数据存放在session里,最后,使用response.sendRedirect(response.encodeRedirectURL("/index.jsp"));将页面定位到index.jsp,response.encodeRedirectURL重写方法可以防止因客户禁用cookie而导致sessionid不能传输的问题。
  • 相关阅读:
    动画02
    动画01
    css过渡
    06强制类型转换
    05强制类型转换
    jetson 安装opencv4.4.0
    cpp中的内置异常
    cpp中std::string和std::wstring 相互转换
    qt creator杂记
    win10 git bash 使用vim 显示 git log
  • 原文地址:https://www.cnblogs.com/duanxz/p/3133449.html
Copyright © 2020-2023  润新知