权限最核心的是业务逻辑,具体用什么技术来实现就简单得多。
通常:用户与角色建立多对多关系,角色与业务模块构成多对多关系,权限管理在后者关系中。
对权限的拦截,如果系统请求量大,可以用Struts2拦截器来做,请求量小可以放在filter中。但一般单级拦截还不够,要做到更细粒度的权限控制,还需要多级拦截。 不大理解filter(过滤器)和interceptor(拦截器)的区别,遂google之。 1、拦截器是基于java的反射机制的,而过滤器是基于函数回调 。
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 起作用 。
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 。
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容 器初始化时被调用一次 。 为了学习决定把两种实现方式都试一下,然后再决定使用哪个。 权限验证的Filter实现: web.xml代码片段 <!-- authority filter 最好加在Struts2的Filter前面-->
<filter>
<filter-name>SessionInvalidate</filter-name>
<filter-class>filter.SessionCheckFilter</filter-class>
<init-param>
<param-name>checkSessionKey</param-name>
<param-value>loginName</param-value>
</init-param>
<init-param>
<param-name>redirectURL</param-name>
<param-value>/entpLogin.jsp</param-value>
</init-param>
<init-param>
<param-name>notCheckURLList</param-name>
<param-value>/entpLogin.jsp,/rois/loginEntp.action,/entpRegister.jsp,/test.jsp,/rois/registerEntp.action</param-value>
</init-param>
</filter>
<!--过滤/rois命名空间下所有action -->
<filter-mapping>
<filter-name>SessionInvalidate</filter-name>
<url-pattern>/rois/*</url-pattern>
</filter-mapping>
<!--过滤/jsp文件夹下所有jsp -->
<filter-mapping>
<filter-name>SessionInvalidate</filter-name>
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>
SessionCheckFilter.java代码 package filter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 用于检测用户是否登陆的过滤器,如果未登录,则重定向到指的登录页面 配置参数 checkSessionKey 需检查的在 Session 中保存的关键字
* redirectURL 如果用户未登录,则重定向到指定的页面,URL不包括 ContextPath notCheckURLList
* 不做检查的URL列表,以分号分开,并且 URL 中不包括 ContextPath
*/
public class SessionCheckFilter implements Filter {
protected FilterConfig filterConfig = null;
private String redirectURL = null;
private Set<String> notCheckURLList = new HashSet<String>();
private String sessionKey = null;
@Override
public void destroy() {
notCheckURLList.clear();
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
if (sessionKey == null) {
filterChain.doFilter(request, response);
return;
}
if ((!checkRequestURIIntNotFilterList(request))
&& session.getAttribute(sessionKey) == null) {
response.sendRedirect(request.getContextPath() + redirectURL);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
private boolean checkRequestURIIntNotFilterList(HttpServletRequest request) {
String uri = request.getServletPath()
+ (request.getPathInfo() == null ? "" : request.getPathInfo());
String temp = request.getRequestURI();
temp = temp.substring(request.getContextPath().length() + 1);
// System.out.println("是否包括:"+uri+";"+notCheckURLList+"=="+notCheckURLList.contains(uri));
return notCheckURLList.contains(uri);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
redirectURL = filterConfig.getInitParameter("redirectURL");
sessionKey = filterConfig.getInitParameter("checkSessionKey");
String notCheckURLListStr = filterConfig
.getInitParameter("notCheckURLList");
if (notCheckURLListStr != null) {
System.out.println(notCheckURLListStr);
String[] params = notCheckURLListStr.split(",");
for (int i = 0; i < params.length; i++) {
notCheckURLList.add(params[i].trim());
}
}
}
} 权限验证的Interceptor实现: 使用Interceptor不需要更改web.xml,只需要对struts.xml进行配置 struts.xml片段 <!-- 用户拦截器定义在该元素下 -->
<interceptors>
<!-- 定义了一个名为authority的拦截器 -->
<interceptor name="authenticationInterceptor" class="interceptor.AuthInterceptor" />
<interceptor-stack name="defualtSecurityStackWithAuthentication">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="authenticationInterceptor" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defualtSecurityStackWithAuthentication" />
<!-- 全局Result -->
<global-results>
<result name="error">/error.jsp</result>
<result name="login">/Login.jsp</result>
</global-results>
<action name="login" class="action.LoginAction">
<param name="withoutAuthentication">true</param>
<result name="success">/WEB-INF/jsp/welcome.jsp</result>
<result name="input">/Login.jsp</result>
</action>
<action name="viewBook" class="action.ViewBookAction">
<result name="sucess">/WEB-INF/viewBook.jsp</result>
</action> AuthInterceptor.java代码 package interceptor;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AuthInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = -5114658085937727056L;
private String sessionKey="loginName";
private String parmKey="withoutAuthentication";
private boolean excluded;
@Override
public String intercept(ActionInvocation invocation) throws Exception { ActionContext ac=invocation.getInvocationContext();
Map<?, ?> session =ac.getSession();
String parm=(String) ac.getParameters().get(parmKey); if(parm!=null){
excluded=parm.toUpperCase().equals("TRUE");
} String user=(String)session.get(sessionKey);
if(excluded || user!=null){
return invocation.invoke();
}
ac.put("tip", "您还没有登录!");
//直接返回 login 的逻辑视图
return Action.LOGIN;
}
} 使用自定义的default-interceptor的话有需要注意几点: 1.一定要引用一下Sturts2自带defaultStack。否则会用不了Struts2自带的拦截器。 2.一旦在某个包下定义了上面的默认拦截器栈,在该包下的所有 Action 都会自动增加权限检查功能。所以有可能会出现永远登录不了的情况。 解决方案: 1.像上面的代码一样,在action里面增加一个参数表明不需要验证,然后在interceptor实现类里面检查是否不需要验证 2.将那些不需要使用权限控制的 Action 定义在另一个包中,这个新的包中依然使用 Struts 2 原有的默认拦截器栈,将不会有权限控制功能。 3.Interceptor是针对action的拦截,如果知道jsp地址的话在URL栏直接输入JSP的地址,那么权限验证是没有效果滴! 解决方案:把所有page代码(jsp)放到WEB-INF下面,这个目录下的东西是“看不见”的 最后我项目里还是使用的filter实现方式,项目变动的少嘛~^_^

转Struts 权限控制的更多相关文章

  1. 使用Struts 拦截namespace进行权限控制

    有时候我需要在几个包下都需要进行同一个权限控制.如在购物网站中,我们需要进入个人中心.下订单.评价商品等等都需要进行登录权限控制,但是这几个模块并不是位于同一个package下.Struts提供的拦截 ...

  2. struts自己定义拦截器--登录权限控制

    说明:该自己定义的拦截器实现用户登录的权限控制. login.jsp--->LoginAction--重定向-->MainAction--->main.jsp 一.1.整体的步骤: ...

  3. Struts2基础-4-2 -struts拦截器实现权限控制案例+ 模型驱动处理请求参数 + Action方法动态调用

    1.新建项目,添加jar包到WEB-INF目录下的lib文件夹,并添加到builde path里面 整体目录结构如下 2.新建web.xml,添加struts2核心过滤器,和默认首页 <?xml ...

  4. Appfuse:权限控制

    Appfuse的权限控制依赖于Struts的Menu机制,common下的menu.jsp是对菜单顺序的定义,详细的菜单项和菜单链接及权限再menu-config.xml中控制,如下: <Men ...

  5. Struts2中基于Annotation的细粒度权限控制

    Struts2中基于Annotation的细粒度权限控制 2009-10-19 14:25:53|  分类: Struts2 |  标签: |字号大中小 订阅     权限控制是保护系统安全运行很重要 ...

  6. Struts2使用拦截器完成权限控制示例

    http://aumy2008.iteye.com/blog/146952 Struts2使用拦截器完成权限控制示例 示例需求:    要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源:否 ...

  7. Struts2使用Interceptor实现权限控制的应用实例详解

    Struts2使用Interceptor实现权限控制的应用实例详解 拦截器:是Struts2框架的核心,重点之重.因此,对于我们要向彻底学好Struts2.0.读源码和使用拦截器是必不可少的.少说了. ...

  8. JAVAEE——BOS物流项目11:在realm中授权、shiro的方法注解权限控制、shiro的标签权限控制、总结shiro的权限控制方式、权限管理

    1 学习计划 1.在realm中进行授权 2.使用shiro的方法注解方式权限控制 n 在spring文件中配置开启shiro注解支持 n 在Action方法上使用注解 3.★使用shiro的标签进行 ...

  9. Shiro入门之二 --------基于注解方式的权限控制与Ehcache缓存

    一  基于注解方式的权限控制 首先, 在spring配置文件applicationContext.xml中配置自动代理和切面 <!-- 8配置自动代理 -->    <bean cl ...

随机推荐

  1. Posix 信号量

    作用 信号量的值为0或正整数,就像红灯与绿灯,用于指示当前是否可以接受任务. 信号量对进程和线程都适用. gcc编译时需加-lpthread 基本函数 信号量的相关函数与标准文件函数非常相似,可以理解 ...

  2. 从零开始学ios开发(五):IOS控件(2),Slider

    下面继续学习ios的其他控件,这次会使用到的控件有Slider,当然还有一些之前已经使用过的控件Label. 这次我们不新建一个project了,当然如果你愿意重新创建一个新的项目也完全可以,我们还是 ...

  3. substr,mb_substr,iconv_substr,array_slice

    通过一个例子来看其关系 /** +---------------------------------------------------------- * 字符串截取,支持中文和其他编码 +----- ...

  4. NET免费服务器

    NET免费服务器 1.先注册一个号.地址:https://appharbor.com/ 2.看看有没有你需要的插件,基本上都是免费的 3.本地创建git库 4.复制git远程仓库的地址 5.推送到远程 ...

  5. css的display属性小实验

    div与span是常用的盒子模型; 区别: div默认是垂直分布(独占一行)   span默认是水平分布(一行可以有多个) 通过float属性可以改变div容器的分布方式达到span容器的效果; 下面 ...

  6. iOS 23 种设计模式

    设计模式主要分三个类型:创建型.结构型和行为型. 其中创建型有: 一.Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二.Abstract Factory,抽象工厂 ...

  7. Django 学习笔记之五 Django中数据库中ManyToManyField及ForeignKey

    1.model里面的代码: from __future__ import unicode_literalsimport django.utils.timezone as timezonefrom dj ...

  8. firefox常用扩展、脚本

    1.AutoPopup.uc.js:鼠标移到菜单和下拉箭头上自动弹出下拉菜单 2.moveButton.uc.js:移动或克隆按钮或菜单到火狐浏览器的任意位置 moveButton.uc.js使用说明 ...

  9. IR的评价指标—MAP,NDCG,MRR

    http://www.cnblogs.com/eyeszjwang/articles/2368087.html MAP(Mean Average Precision):单个主题的平均准确率是每篇相关文 ...

  10. [resource]Github上维护的一个机器学习相关的框架,库和工具列表

    https://github.com/josephmisiti/awesome-machine-learning  A curated list of awesome Machine Learning ...