当前位置: 首页 > 面试题库 >

使用拦截器来验证用户访问权限

施梓
2023-03-14
问题内容

我正在尝试使用Interceptor来限制用户执行某些操作。

ContainsKeyInterceptor

public class ContainsKeyInterceptor extends AbstractInterceptor implements SessionAware {
    private static final long serialVersionUID = 1L;

    private Map<String, Object> session;

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        if(session == null) {
            System.out.println("session is null");
        }

        if(session.containsKey("currentId")) {
            return "index";
        }

        String result = actionInvocation.invoke();

        return result;
    }

    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }
}

如果currentId在中找到用户,则应该将用户重定向到索引页面session

但是,我得到了一个NullPointerException,说session是空的,如if-check所验证。

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.devMode" value="false" />

    <!-- actions available to guests -->
    <package name="guest" extends="struts-default">
        <interceptors>
            <interceptor name="containskeyinterceptor" class="com.mypackage.interceptor.ContainsKeyInterceptor" />
        </interceptors>

        <action name="index" class="com.mypackage.action.IndexAction">
            <interceptor-ref name="containskeyinterceptor" />
            <result type="redirect">/index.jsp</result>
            <result name="index" type="redirect">/index.jsp</result>
        </action>

        <action name="login" class="com.mypackage.action.LoginAction">
            <interceptor-ref name="containskeyinterceptor" />
            <result type="redirect">/index.jsp</result>
            <result name="input">/login.jsp</result>
            <result name="index" type="redirect">/index.jsp</result>
        </action>       
    </package>

    <!-- actions available to members -->
    <package name="member" extends="struts-default">
        <action name="logout" class="com.mypackage.action.LogoutAction">
            <result type="redirectAction">
                <param name="actionName">index</param>
            </result>
        </action>
    </package>
</struts>

为什么是sessionnull以及如何解决?

(这是我使用的参考。)


问题答案:

Struts Session只是Map<String,Object>底层的包装HttpSession

虽然实现SessionAware接口是在Action中获取它的正确方法,但是如果要从Interceptor中获取它,则需要执行以下操作:

要获取Struts 会话图

@Override
public String intercept(ActionInvocation ai) throws Exception {
    final ActionContext context = ai.getInvocationContext();

    // Struts Session
    Map<String, Object> session = context.getSession();

要获得真正的 HttpSession对象

@Override
public String intercept(ActionInvocation ai) throws Exception {
    final ActionContext context = ai.getInvocationContext();

    HttpServletRequest request = (HttpServletRequest)context.get(StrutsStatics.HTTP_REQUEST);

    // Http Session
    HttpSession session = request.getSession();

就是说,您没有在动作中获得会话(也没有其他任何参数,对象等)的原因是,您陷入一个常见错误: 仅应用一个 (您的) 拦截器, 而不是
应用整个拦截器堆栈 (其中应包含您的):

您可以在每个动作中定义两次:

<action name="login" class="ph.edu.iacademy.action.LoginAction">
    <interceptor-ref name="defaultStack" /> <!-- this is missing -->
    <interceptor-ref name="containskeyinterceptor" />

或者更好的是,在自定义堆栈中定义一次,并始终使用堆栈:

<interceptors>
    <interceptor-stack name="yourStack">                
       <interceptor-ref name="defaultStack"/>
       <interceptor-ref name="containskeyinterceptor"/>
    </interceptor-stack>
</interceptors>

<action name="login" class="ph.edu.iacademy.action.LoginAction">
    <interceptor-ref name="yourStack" />

并最终使用default-interceptor-ref定义它,以避免为该程序包的每个操作配置编写它:

<default-interceptor-ref name="yourStack"/>

<action name="login" class="ph.edu.iacademy.action.LoginAction">


 类似资料:
  • 本节,我们将通过 Spring MVC 拦截器(Interceptor)来实现一个用户登录权限验证的案例。 在本案例中,只有登录后的用户才能访问系统主页,若没有登录就直接访问主页,则拦截器会将请求拦截并跳转到登录页面,同时在登录页面中给出提示信息。若用户登陆时,用户名或密码错误,则登录页也会显示相应的提示信息。已登录的用户在系统主页点击“退出登录”时,跳转会登录页面,流程图如下。 图1:用户登录流

  • 我需要使用拦截器验证并记录grpc服务请求的一些数据。我检查了ServerInterceptor的interceptCall,但找不到获取请求对象的方法。有没有办法让请求对象进入拦截器?

  • 我一直在使用字节好友来监控应用程序的行为,我想在执行特定方法之前检查其中一个应用程序类的数组字段是否已更新。我已经阅读了字节好友留档和堆栈溢出问题,并找到了一些有用的留档,了解如何使用拦截字段访问。 然而,因为我感兴趣的领域是一个数组,中的和事件似乎无关紧要。 是否可以使用ByteBuddy跟踪数组字段的更新?

  • 我有以下场景:我正在尝试处理一个表单,模型属性是一个具有String和Long属性的bean。众所周知,bean验证提供了很多注释来帮助我们确定数据的有效性。我面临的是,对于Long属性的情况,我只能使用@NotNull和另一个注释(我不记得它的名字)来强制用户输入正数。如果用户输入例如“sdf”,应用程序会抛出一个BIG异常。所以我想知道的是,如果用户在爆炸前输入了一个数字(因为我不能使用@Pa

  • 我正在尝试使用,我想将添加到我的像这样: 但下面的不起作用: 我的服务器是asp。net webApi。请帮忙,我该怎么办?

  • X1.5.0新增 sp_auth_check($uid,$name=null,$relation='or') 功能: 用户权限验证 参数: $uid: 当前登录用户或者管理员的id $name:需要验证的规则列表,支持逗号分隔的权限规则或索引数组,默认为当前url $relation:如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证 返回: 类型