在action方法上定义注解通过拦截器解析
通过命名规则规定action类名对应模块标示名, ?action中方法名对应模块的crud 权限值,
add*对应添加权限,del*对应删改,update*对应更改,其它方法为查询权限。
及时认证权限的时候有的action命名难以对应,需要配置xml 或者 定义注解 通过拦截器解析转换?
?
?
?
一、注解类源码
?
@Retention(RetentionPolicy.RUNTIME)//运行时解析@Target(ElementType.METHOD)//在方法中定义public @interface AuthPermission {public String moduleSn() default "";public int permission() default -1;public boolean ignore() default false;}
?
?
二、被注解的类ignore=true 不需要及时认证
?
@Controller("loginAction")@Scope("prototype")public class LoginAction {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Resourceprivate UserManager userManager;@Resourceprivate AclManager aclManager;//执行登录操作public String execute(){User user = userManager.login(username, password);ServletActionContext.getRequest().getSession().setAttribute("login", user);return "back_index";}@AuthPermission(ignore=true)public String outlook(){User user = (User)ServletActionContext.getRequest().getSession().getAttribute("login");List modules = aclManager.searchModules(user.getId());ActionContext.getContext().put("modules", modules);return "outlook";}@AuthPermission(ignore=true)public String main(){return "main";}}
?
?
?
三、定义及时认证的拦截器
public class AuthInterceptor extends AbstractInterceptor {@Overridepublic String intercept(ActionInvocation invocation) throws Exception {//从http session中获取用户的IDint userId = ((User)ServletActionContext.getRequest().getSession().getAttribute("login")).getId();//取出action的名称,作为当前正在请求的模块的唯一标识String actionName = invocation.getProxy().getActionName();String moduleSn = actionName;int permission = Permission.READ;//根据请求的方法的名称,来判断要执行的操作String methodName = invocation.getProxy().getMethod();if(methodName != null){if(methodName.startsWith("add")){permission = Permission.CREATE;}if(methodName.startsWith("update")){permission = Permission.UPDATE;}if(methodName.startsWith("del")){permission = Permission.DELETE;}}boolean ignore = false;//如果定义了注解,则使用注解中的配置信息Method method = invocation.getAction().getClass().getMethod(methodName);AuthPermission ap = method.getAnnotation(AuthPermission.class);if(ap != null){if(!ap.moduleSn().equals("")){moduleSn = ap.moduleSn();}if( ap.permission() != -1){permission = ap.permission();}ignore = ap.ignore();}if(!ignore){BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletActionContext.getServletContext());AclManager aclManager = (AclManager)factory.getBean("aclManager");if(!aclManager.hasPermissionByModuleSn(userId, moduleSn, permission)){throw new RuntimeException("您无权执行本操作,请联系系统管理员!");}}return invocation.invoke();}}
?
注解的总结
?
?
?用于控制类方法的调用,只有拥有某个角色时才能调用。
1 楼 nothink 2010-03-29 这样的做法并不可取。因为有时候会直接调用了jsp。那你的interceptor就失效了。所以我觉得如果是做这个功能。最好还是转换成filter去实现。但是用filter就与sturts2无关了。 2 楼 ysen 2010-03-29 nothink 写道这样的做法并不可取。因为有时候会直接调用了jsp。那你的interceptor就失效了。所以我觉得如果是做这个功能。最好还是转换成filter去实现。但是用filter就与sturts2无关了。有道理
3 楼 former 2010-03-31 可以用spring security拦截url做正则匹配来授权——其实也是filter。
不推荐直接访问jsp的做法,不安全,复杂的适合,封装也不是太好。在我们的应用中,jsp都放在WEB-INF下。