针对合法的登陆,(一)和(二)的解决方案,已经解决了用户针对模块和功能点的权限控制问题。但是如果用户如果在地址栏手动写入以前已经识记的URL地址,那么用户就可以获取他所没有

的权限而进行相关的操作。为了解决这个问题,提出了以下方案:

       把系统中的某一模块下所有链接地址全部录入数据库,然后根据请求地址和数据库已记录的地址进行对比,以此进行控制权限的判断。
       
     一:把链接地址存入数据库

       把系统中用到的地址存入PAGE_OPERATION_TABLE,其中PAGE_ID为某一系统功能点的入口PAGE,OPERATION_IS_VALID判断是否需要进行权限判断。

    二:对系统的ACTION进行拦截。

    *Action如果继承自DispatchAction,则重写*Action的execute()方法。
   
@Override
    
public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
return super.execute(mapping, form, request, response);
    }


      配置拦截器:

     
    <bean id="myInterceptor"
        
class="net.better_best.www.utils.AopPriviledge">
    
</bean>

    
<aop:config>
        
<aop:aspect id="aop" ref="myInterceptor">
            
<aop:pointcut
                expression
="execution ( org.apache.struts.action.ActionForward net.better_best.www.*.action.*.*(..))"
                id
="mycut" />
            
<aop:around pointcut-ref="mycut" method="doBasicProfiling" />
        
</aop:aspect>
    
</aop:config>

     实现拦截方法:

   
package net.better_best.www.utils;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionMapping;
import org.aspectj.lang.ProceedingJoinPoint;

public class AopPriviledge {

    @SuppressWarnings(
"unchecked")
    
/*
     * aop拦截,环绕通知,实现权限拦截; String name:根据name判断管理员或会员;n代表管理员,m代表会员,n或m的值代表特定的操作;
     
*/

    
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        Object[] obj 
= pjp.getArgs();
        ActionMapping mapping 
= (ActionMapping) obj[0];
        HttpServletRequest request 
= (HttpServletRequest) obj[2];
        String mappingName 
= "";
        
if (SessionUtil.getSessionManager(request) != null && request.getParameter("n")!=null{
            mappingName 
= "error_manager";
            String requestPath 
= mapping.getPath()+ ".do?"+ request.getQueryString().substring(0,request.getQueryString().indexOf("&"));
            List priviledgeList 
= (List) request.getSession().getAttribute("managerPriviledge");
            
if (priviledgeList.contains(requestPath.trim())) {
                
return priviledge(pjp, request);
            }
 else {
                
return mapping.findForward(mappingName);
            }


        }
 else if (SessionUtil.getSessionUser(request) != null && request.getParameter("m")!=null{
            mappingName 
= "error_user";
            Collection userPriviledge 
= (Collection) request.getSession().getAttribute("userPriviledge");
            
if (userPriviledge.contains(mapping.getPath().trim())) {
                
return priviledge(pjp, request);
            }
 else {
                
return mapping.findForward(mappingName);
            }

        }
 else if (SessionUtil.getSessionUser(request) == null && request.getParameter("m")!=null{
            
return mapping.findForward("userindex");
        }
 else if (SessionUtil.getSessionManager(request) == null&& request.getParameter("n")!=null{
            
return mapping.findForward("index");
        }
 else
            
return mapping.findForward("priviledge_error");

    }


    
/*
     * 实现真正的权限拦截; String value :某一个权限值,为pageId; List<PageTable> module:
     * PageTable的集合,为某一用户的某一模块所具有的页面功能集; String mappingName:代表页面URL,程序异常跳转之;
     
*/

    
private Object priviledge(ProceedingJoinPoint pjp,
            HttpServletRequest request) 
throws Throwable {
        Object result 
= null;
        
long begintime = new Date().getTime();
        result 
= pjp.proceed();
        
long endtime = new Date().getTime();
        
long time = endtime - begintime;
        System.out.println(
"====================================================================================================================");
        System.out.println(pjp.getTarget().getClass().getSimpleName() 
+ "     "+ request.getQueryString() + "      耗时          " + time+ "          ms");
        System.out.println(
"====================================================================================================================");
        
return result;
    }


}



缓存权限:

  List priviledgeList = pageService.getPriviledgeForManager(""+manager.getManagerNroleId());
           request.getSession().setAttribute(
"managerPriviledge", priviledgeList);


以上步骤是针对URL写入的权限控制的解决方案进行了大致的记录。

Feedback

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-17 15:58 by dragon904
有没有实现数据权限?不同的用户可以访问不同的数据。

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-17 16:07 by java小爬虫
@dragon904
不太明白,
你的意思是不是信息类型,信息发布人类型,以及发布人等概念,这个在在信息表里面可以定义字段,然后在SQL中加入条件可以查询啊。

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-17 16:15 by 独孤行
我们现在的项目就是用这个方法做权限管理。。。

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-17 16:27 by Lancelot
你发的这三个东西实在太粗糙了,一些基础功能都没有考虑到(比如多场景多角色),基本上没有什么可取的地方。
这么说可能有点儿打击你,但事实就是如此。
建议你去好好看看acegi(spring-security)的实现方式;如果非要自己实现的话,也可以考虑用位运算的方式来进行匹配,也会比字符串匹配的效率要高不少。

另外@dragon904
你提出的问题不是访问权限需要去考虑的问题,是需要通过数据范围去约束的,请不要混为一谈。

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-17 18:00 by 53中文网
没怎么看明白

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-23 14:16 by IT者
可读性太差,说实话,如果你这种做法用到项目中,以后你就天天等着哭吧。

# re: 用户权限的解决方案(三)----------URL写入的权限控制[未登录]  回复  更多评论   

2010-06-23 23:22 by bobby
@Lancelot
能不能详细介绍一下用位运算的方式如何匹配,谢谢!

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-06-24 08:54 by java小爬虫
@IT者

这位兄弟,有什么问题说清楚一点啊,

我最讨厌夸夸其谈的人了。

# re: 用户权限的解决方案(三)----------URL写入的权限控制  回复  更多评论   

2010-07-02 09:16 by 威尔
我强烈建议你去学习巴巴运动网视频

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问