您现在的位置:首页 >> 基础 >> Java编程 >> 内容

struts2, 注销账号后, 通过地址栏访问action仍然可以登录的问题--Java学习网

时间:2016-12-2 8:02:39

  核心提示:问题: 用struts2结合spring做了一个用户登录的, 然后点击之后可以注销的例子. 登录页面很简单, 大概就是像如下这个样子    登录的action和注销的action在strut.xml中...

问题: 用struts2结合spring做了一个用户登录的, 然后点击之后可以注销的例子.

      登录页面很简单, 大概就是像如下这个样子

  

  登录的action和注销的action在strut.xml中为如下配置:

<action name="checkUser" class="checkUserAction" method="execute">       //这里的class="checkUserAction"是获取的spring配置文件中的bean
  <result name="login">/WEB-INF/jsp/login/login.jsp</result> //这里是登录失败的话, 会重新返回到登录页面 
  <result name="success">/WEB-INF/jsp/list/home.jsp</result> //这里是登录成功的话, 会进入到欢迎界面
</action>

<action name="quitUser" class="checkUserAction" method="quitUser"> //注销的action,注销成功返回登录页面

  <result name="success">/WEB-INF/jsp/login/login.jsp </result>  

</action>



   spring的配置文件如下:

<bean id="administrator" class="pojo.Administrator">
    </bean>
    
    <bean id="checkUserAction" class="action.checkUserAction" scope="prototype">
        <property name="adminer">
            <ref bean="administrator"/>
        </property>
        <property name="adminUserService">
            <ref bean="adminUserServiceImpl"/>
        </property>
    </bean>

checkUserAction的源代码如下:

public class checkUserAction extends ActionSupport implements ModelDriven<Administrator>{
    Administrator adminer;
    AdminUserService adminUserService;
    @Override
    public String execute() throws Exception {
        String result = adminUserService.findAdministrator(adminer);  //这里的一行, 是我在将表单提交过来的用户名密码和数据库中的做对比, 如果成功就将这个放入session, 失败的话就做相应的提示,
        if(!result.equals("success"))
        {
            if(result.equals(AdminUserService.NOT_EXIST))
            {
                ServletActionContext.getRequest().setAttribute("error", "用户名不存在");
            }
            else if(result.equals(AdminUserService.WRONG_PASSWORD))
            {
                ServletActionContext.getRequest().setAttribute("error", "密码错误");
            }
            return "login";
        }
        ActionContext.getContext().getSession().put("adminUser", adminer);
        return result;    
    }
    
  /*下述为注销用户时使用的方法, 将session清空*/
public String quitUser() throws Exception {     ActionContext.getContext().getSession().clear(); return "success"; } ......get和set方法略, 并且模型驱动的部分也略 }

  就是这么一个简单的程序, 登录没问题, 退出也可以正常退出. 但是这里我却发现了一个严重的问题,

  就是我在点击退出之后, 通过在地址栏直接输入action的地址:"http://localhost:8080/xxx/checkUser" 来绕过通过点击"登录"按钮, 直接访问的时候, 居然可以正常登录到欢迎界面!!!

  这个问题困扰了我很久, 在网上也查了很多方法:

  1. 有人说需要建立拦截器, 通过在拦截器中屏蔽不合法的登录用户可以做到, 后来我尝试了不行.

  2. 还有的说要禁止动态访问, 可我发现我的页面本身就是默认禁止动态访问的action中的method的. (只不过人家是直接访问的action的名字, 不是访问的action中的method).

  3. 我又查, 看struct2能够直接屏蔽在地址栏直接输入action的名字来进行访问的方法, 似乎也米有这种方法, 也就说地址栏是肯定可以直接输入action的名字来进行访问的!

    继续分析, 我在checkUserAction 中, 加了打印, 直接将用来获取表单数据的adminer对象(也就是存放用户名密码)里面的数据都打了出来, 居然打出来的值也都是正确的. 然后我就很纳闷了, 我明明已经退出登录了, 通过strut2的标签<s:debug/>检查, session里面确实已经没有任何东西了, 但是通过地址栏访问checkUser这个action的时候, 居然那个adminer对象里面还有值! 而我又不是通过点击表单的登录按钮, 而是通过直接在地址栏访问action来访问的页面, 那么这个正确的数据到底是谁提交的呢? 然后, 我又把浏览器的抓包工具打开, 发现我在直接访问action的时候, 确实里面也没有附带任何的表单(用户名密码)信息, 那这个值到底是谁给装进去的呢?

  我然后, 又怀疑, 是不是模型驱动干了什么坏事? 是不是模型驱动在我退出的时候, 把用户名密码给装填了进去, 然后发回给了浏览器, 但是后来看了下模型驱动的源码, 模型驱动仅仅在action执行之前的时候, 会把获取到的表单数据, 通过一个模型压入到值栈中, action执行完之后, 并没有做任何事情. 而且我还做了这样的操作, 我在quitUser()的函数中, 在返回"success"之前, 把值栈里面所有的内容也都给清空了, 然而, 问题依旧!!!

  最后最后, 我才忽然发现了一个问题, 既然通过地址栏直接访问action地址, 是无法提交表单数据的, 同时session中的数据也清空了, 那只能说明一个问题, 就是这个 adminer对象里面的值肯定是服务器给赋进去的! 于是自然而然的想到了肯定是spring的问题. 原因: 因为spring在产生action对象时, 应该是多实例的, 就是每有一个请求, 就会产生一个action对象, 这是没问题的. 但问题是, 我在配置checkUserAction的时候, 没有把它的属性adminer对象也给赋值成多实例, 导致了在下一次的action中, spring返回给action使用的adminer对象, 仍然是之前成功登录过一次的那个adminer对象, 这个对象里面仍然保存着上一次成功登录时的用户名密码信息, 因此, 直接访问地址栏的时候, 它直接就用了之前的这个对象去进行验证了, 那当然是可以通过的了. 这就是问题的根本所在.

  其实经验证, 我通过地址栏访问checkUser这个Action, 登录后的页面里面, 打开<s:debug/>开关, 能够看到每一次访问之后, session中存的那个adminer对象的值都没变化过, 就能够说明这个问题.

  所以, 只需将spring配置文件里面<bean id="administrator" class="pojo.Administrator" scope="prototype">下面这一行, 将其改为多实例即可.

Java免费学习   Java自学网 http://www.javalearns.com

关注微信号:javalearns   随时随地学Java

或扫一扫

随时随地学Java

作者:不详 来源:网络
    你是从哪里知道本网站的?
  • 网友介绍的
  • 百度搜索的
  • Google搜索的
  • 其它搜索过来的
  • 网址输错了进来的
  • 太忙了不记得了
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • java学习网(www.javalearns.com) © 2014 版权所有 All Rights Reserved.
  • Email:javalearns@163.com 站长QQ:1356121699 晋ICP备14003680号-3
  • java学习网部分内容来自网络或网友发布,如侵犯了您利益,请发邮件至:javalearns@126.com,我们尽快处理!
  • Java学习网
  • 网站统计
  • 晋公网安备 14042902000001号