Web应用安全控制

本内容摘自《Java Web程序设计基础教程》

13 系统安全控制


目标:

u 掌握使用登录功能对系统的用户进行认证;

u 掌握如何控制只有具有相应权限的用户才可以访问相应的资源;

u 掌握如何控制页面中的部分功能只能在特定的情况下才能使用;

u 掌握如何对多个文件的安全同时进行控制;

u 了解验证码的工作原理。

网站的很多功能是普通用户不能访问的,例如添加图书这样的功能只能由管理员完成,普通用户是无法访问的,如果普通用户要访问,应该提示普通用户没有相应的权限。本章介绍如何控制用户的权限。

13.1 完善登录功能

456章中介绍的登录功能只是简单的模拟,现在对该功能进行完善。

13.1.1 功能描述

用户在登录界面输入用户ID和口令,系统根据用户输入的用户ID和口令进行处理:

l 用户ID和口令都正确,并且当前用户是管理员,则跳转到管理员的默认界面。

l 如果用户ID和口令正确,并且是普通用户,则跳转到普通用户的默认界面。

l 如果用户ID和口令不正确,则重新转向登录界面。

不管是管理员还是普通用户,登录之后的默认界面应该是用户使用频率最高的界面。如果网站比较智能,可以对用户的访问进行统计,为用户显示经常使用的界面,或者上次访问的界面。对于管理员来说,使用频率最高的功能应该是订单管理,所以应该把订单管理作为管理员的默认界面。对于普通用户来说,使用频率最高的功能应该是图书查看,所以应该把图书查看界面作为普通用户的默认界面。

13.1.2 思路分析

仍然采用MVC模式来设计该功能。

首先是M部分,可以使用UesrBean中原有的方法findUserById

其次是V部分,登录界面在前面已经完成,图书查看功能是读者在前面实训中完成的功能,假设为findBooks,订单管理是下一章将要完成的实训内容,假设为findOrders

最后是C部分,获取用户输入的用户ID和口令,根据ID调用模型的findUserById方法,根据返回值进行处理:

u 如果返回值为null,则说明用户不存在;

u 否则,判断口令是否匹配:

n 如果不匹配,说明口令不正确;

n 如果匹配,判断用户的类型:

u 如果用户类型为1,说明该用户为管理员;

u 否则为普通用户。

13.1.3 修改登录控制器Servlet

根据上面的分析,修改后的控制器的代码如下:

package bookstore.servlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import bookstore.bean.*;

public class LoginServlet extends HttpServlet

{

public void doGet(HttpServletRequest request,HttpServletResponse response)

throws IOException,ServletException {

// 获取用户提交的信息

String userid = request.getParameter("userid");

String userpass = request.getParameter("userpass");

// 创建JavaBean对象

UserBean ub = new UserBean();

// 转向的文件

String forward=null;

// 提示信息

String info=null;

UserBean user=ub.findUserById(userid);

// 用户不存在

if(user == null){

forward="login.jsp";

}

// 口令不正确

else if(!user.getUserpass().equals(userpass)){

forward="login.jsp";

}

// 管理员

else if(user.getType().equals("1")){

forward="findOrders";

}

// 普通用户

else{

forward="findBooks";

}

// 定义跳转文件

RequestDispatcher rd=request.getRequestDispatcher(forward);

// 完成重定向

rd.forward(request,response);

}

public void doPost(HttpServletRequest request,HttpServletResponse response)

throws IOException,ServletException {

doGet(request,response);

}

}

13.2 用户管理的安全控制

13.2.1 功能描述

只有管理员可以使用图书添加功能,如果用户没有登录,提示用户“您还没有登录,请先登录!”,如果当前用户是普通用户,提示用户“您不是管理员,不能添加用户”。如果当前用户是管理员,则显示添加界面。

13.2.2 运行效果

首先,直接访问图书添加的页面,得到如图13.1所示界面。

13.1 没有登录的提示界面 13.2 没有权限的提示界面

然后,点击“登录”超链接跳转到登录界面,输入普通用户的ID和口令,然后再访问图书添加界面,得到如图13.2所示界面。

然后,点击“登录”超链接跳转到登录界面,输入管理员用户ID和口令,然后再访问图书添加界面,得到如图9.1所示的用户添加界面。

13.2.3 思路分析

要防止这个文件被没有权限的人访问,必须对每个访问这个文件的人的身份进行验证,要想知道当前用户的权限,在登录的时候必须记录当前用户的权限。

在访问这个文件的时候,首先应该从session中获取用户信息,如果用户不存在,跳转到“没有登录”的提示界面,如果用户是普通用户,跳转到“没有权限”的提示界面,不让用户访问当前页面,这样就保证了当前页面的安全。

为了方便用户的操作,需要在信息提示页面增加到登录页面的超链接。

13.2.4 操作session

使用session对象能够在多个页面之间共享信息,在Servlet中也可以使用session对象,但是与在JSP中不同,在JSPsession对象是内部对象,在Servlet中需要先获取session对象。要完成安全控制需要使用session对象保存用户信息,下面介绍关于session的常用操作。

获取session对象

session对象存储在request对象中,request对象也就是服务类方法的第一个参数,可以使用HttpServletRequest的下面的方法来获取session对象:

HttpSession getSession(boolean);

通常是在doGet方法或者doPost方法中,通过第一个参数request来获取。代码如下:

HttpSession session;

session =request.getSession(true);

session中存储信息

获取session对象之后,如果希望在session中存储信息,可以使用下面的方法:

session.setAttribute("name",value);

用于在session中保存信息,有两个参数,第一个参数是字符串,是要存储信息的名字,第二个参数是保存的值本身,可以是各种类型的对象。如果第一个参数所指定的名字存在,会替换该名字原来对应的值;如果第一个参数所指定的名字不存在,会把第二个参数指定的值存储到session中。

session中获取信息

如果要从session中获取已经保存的信息,可以使用下面的方法:

session.getAttribute("name");

参数就是要获取的信息的名字。在使用的时候对得到的信息必须进行强制类型转换,因为方法的返回值类型是Object。例如在session中存储的是String对象,要得到这个对象,可以使用下面的代码:

String str = (String)session.getAttribute("name");

删除session中存储的信息

如果要删除session中的某个信息,可以使用下面的方法进行删除:

session.remove("name");

参数就是要删除的session中的对象的名字。

使session失效

如果不想使用session了,可以使用下面的方法:

session.invalidate()

使用该方法之后,就不能继续使用session了,包括session中的所有信息。

13.2.5 修改登录处理的代码

在登录成功之后,把用户信息保存到session中。因为这个信息是与特定用户相关的,在用户的整个访问过程中都有效。

Servlet中首先要获取session对象,在用户登录成功之后,把用户对象保存到session中。修改后的Servlet的代码如下:

package bookstore.servlet;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import bookstore.bean.*;

public class LoginServlet extends HttpServlet

{

public void doGet(HttpServletRequest request,HttpServletResponse response)

throws IOException,ServletException {

// 获取用户提交的信息

String userid = request.getParameter("userid");

String userpass = request.getParameter("userpass");

// 创建JavaBean对象

UserBean ub = new UserBean();

// 转向的文件

String forward=null;

// 提示信息

String info=null;

// 得到session对象

HttpSession session;

session =request.getSession(true);

UserBean user=ub.findUserById(userid);

// 用户不存在

if(user == null){

forward="login.jsp";

}

// 口令不正确

else if(!user.getUserpass().equals(userpass)){

forward="login.jsp";

}

// 管理员

else if(user.getType().equals("1")){

session.setAttribute("login",user);

forward="findOrders";

}

// 普通用户

else{

session.setAttribute("login",user);

forward="findBooks";

}

// 定义跳转文件

RequestDispatcher rd=request.getRequestDispatcher(forward);

// 完成重定向

rd.forward(request,response);

}

public void doPost(HttpServletRequest request,HttpServletResponse response)

throws IOException,ServletException {

doGet(request,response);

}

}

13.2.6 在用户添加界面增加控制

在原来的添加界面的代码中,增加对用户是否登录已经是否有相应的权限的判断。判断过程如下:

u session中获取“login”对象,如果不存在表示没有登录,转向需要登录的提示界面;

u 如果用户存在,并且是普通用户,转向没有权限的提示界面;

u 如果是管理员,继续向下执行即可。

用于判断的代码如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!--判断session中是否存在login-->

<c:if test="${empty login}">

<!--跳转到需要登录的提示界面-- >

<jsp:forward page="needlogin.jsp"/>

</c:if>

<!--判断session中用户是否是管理员-->

<c:if test="${login.type==0}">

<!--跳转到没有权限的提示界面-->

<jsp:forward page="noright.jsp"/>

</c:if>

把这段代码添加到addUser.jsp页面的前面即可。

13.2.6 对控制器进行安全控制

上面完成了对添加用户的界面的安全控制,这样如果不是管理员就不能访问这个界面了。好像已经完成了安全控制,事实是不是这样呢?

添加用户的过程是:在添加界面输入用户信息,提交给控制器处理,控制器调用业务方法完成添加过程。如果用户直接访问控制器怎么办?因为控制器是Servlet,是允许访问的。

有人会说虽然可以访问,但是没有用户信息,仍然不能添加。实际上,可以通过问号传递参数,效果与表单提交完全相同。在前面讲分页显示的时候,页码就是通过问号传递的。所以要想保证用户添加功能的安全,还需要对控制器进行安全控制。

在控制器中进行安全控制,主要的过程:

u session中获取登录信息

u 然后对登录信息进行判断:

n 如果为null,说明用户没有登录,跳转到“需要登录”的提示界面;

n 如果不为

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值