2006年6月28日 #
簡單實用一分鐘上手級權(quán)限控制
找回來自己以前的一個項目, 用的是通過filter過濾來管理權(quán)限的方法, 很簡單,但也很實用。 這個項目并不小,但這么一個類就已經(jīng)可以滿足其權(quán)限管理的需要了,所以其實很多時候,權(quán)限管理大家并不必要想得那么復(fù)雜, 對于不少系統(tǒng),簡單通過filter來管理就ok了, simple 也是一種美^_^ 在web.xml里加入
- <!--================權(quán)限?設(shè)置================-->??
- <filter>??
- ????<filter-name>Authentication</filter-name>??
- ????<filter-class>com.springside.demo.security.UrlFilter</filter-class>??
- ????<init-param>??
- ????????<param-name>onError</param-name>??
- ????????<param-value>/login.jsp</param-value>??
- ????</init-param>??
- </filter>??
- <filter-mapping>??
- ????<filter-name>Authentication</filter-name>??
- ????<!--?只過濾?.jsp?結(jié)尾的url,?其余的如?.do,?.html,?.jpg,?.css?等不作過濾-->??
- ????<url-pattern>*.jsp</url-pattern>??
- </filter-mapping>??
?
UrlFilter filter類的實現(xiàn)
- public?class?UrlFilter?implements?Filter?{??
- ????private?FilterConfig?filterConfig;??
- ??
- ????private?FilterChain?chain;??
- ??
- ????private?HttpServletRequest?request;??
- ??
- ????private?HttpServletResponse?response;??
- ??
- ????public?void?destroy()?{??
- ????????this.filterConfig?=?null;??
- ????}??
- ??
- ????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{??
- ????????this.filterConfig?=?filterConfig;??
- ????}??
- ??
- ????public?void?doFilter(ServletRequest?servletRequest,??
- ????????????ServletResponse?servletResponse,?FilterChain?chain)??
- ????????????throws?IOException,?ServletException?{??
- ????????this.chain?=?chain;??
- ????????this.request?=?(HttpServletRequest)?servletRequest;??
- ????????this.response?=?((HttpServletResponse)?servletResponse);??
- ??
- ????????String?url?=?request.getServletPath();??
- ????????if?(url?==?null)??
- ????????????url?=?"";??
- ??
- ????????//?獲取session中的loginuser對象??
- ????????HttpSession?session?=?request.getSession();??
- ????????LoginUser?loginuser?=?(LoginUser)?session.getAttribute("loginuser");??
- ??
- ????????if?(baseUrl(url,?request))?{??
- ????????????//?如果是登陸界面等無須<u><b><font?color="#FF0000">權(quán)限</font></b></u>訪問的的公用界面則跳過??
- ????????????chain.doFilter(request,?response);??
- ????????}?else?if?(loginuser?==?null)?{??
- ????????????checkLogin(url);??
- ????????}?else?{??
- ????????????verifyUrl(url,?loginuser);??
- ????????}??
- ????}??
- ??
- ????private?void?checkLogin(String?url)?throws?ServletException,?IOException?{??
- ????????//?如果session中獲取不到?loginuser?對象,要不就是session?過期了,要不就是還沒登陸。所以返回登陸界面??
- ????????//?在登陸后記得把?loginuser?對象置于?session中??
- ??
- ????????if?(url.indexOf("/index.jsp")?>=?0??
- ????????????????&&?"login".equals(request.getParameter("act")))?{??
- ????????????//?獲取request中username,password??
- ????????????String?username?=?request.getParameter("username");??
- ????????????String?password?=?request.getParameter("password");??
- ????????????UserDao?userDao?=?new?UserDao();??
- ????????????if?(userDao.authUser(username,?password))?{??
- ????????????????LoginUser?user?=?userDao.getUser(username);??
- ????????????????request.getSession().setAttribute("loginuser",?user);??
- ????????????????verifyUrl(url,user);??
- ????????????????return;??
- ????????????}??
- ????????}??
- ????????response.sendRedirect("login.jsp");??
- ????}??
- ??
- ????private?void?verifyUrl(String?url,?LoginUser?loginuser)??
- ????????????throws?IOException,?ServletException?{??
- ????????//?獲取?loginuser?擁有的所有資源串??
- ????????Set?royurl?=?loginuser.getResStrings();??
- ????????if?(royurl?!=?null?&&?royurl.size()?>?0?&&?pass(royurl,?url,?request.getParameterMap()))?{??
- ????????????chain.doFilter(request,?response);??
- ????????}?else?{??
- ????????????response.setContentType("text/html;charset=GBK");??
- ????????????response??
- ????????????????????.getWriter()??
- ????????????????????.println(??
- ????????????????????????????"<div?style='margin:?100?auto;text-align:?center;"??
- ????????????????????????????????????+?"font:?bold?18px?宋體;color:?#0066CC;vertical-align:?middle'>?Sorry,您沒有<u><b><font?color="#FF0000">權(quán)限</font></b></u>訪問該資源!</div>");??
- ????????}??
- ????}??
- ??
- ????/**?
- ?????*?判斷是否是公用界面?
- ?????*/??
- ????protected?boolean?baseUrl(String?url,?HttpServletRequest?request)?{??
- ????????if?(url.indexOf("/login.jsp")?>=?0)?{??
- ????????????return?true;??
- ????????}??
- ????????return?false;??
- ????}??
- ??
- ????/**?
- ?????*?判斷該用戶是否有權(quán)請求該url?
- ?????*??
- ?????*?@param?royurl?
- ?????*????????????user擁有的授權(quán)的的url串集合?
- ?????*?@param?url?
- ?????*????????????當(dāng)前請求的url?
- ?????*?@param?reqmap?
- ?????*????????????當(dāng)前request的參數(shù)?
- ?????*?@return?是否通過該url?
- ?????*/??
- ????protected?boolean?pass(Set?royurl,?String?url,?Map?reqmap)?{??
- ????????boolean?match?=?true;??
- ????????for?(Iterator?iter?=?royurl.iterator();?iter.hasNext();)?{??
- ????????????//?獲取資源??
- ????????????match?=?true;??
- ????????????String?res_string?=?(String)?iter.next();??
- ????????????if?(res_string.indexOf("*")?>?0)?{??
- ????????????????res_string?=?res_string.substring(0,?res_string.indexOf("*"));??
- ????????????????if?(url.substring(0,?res_string.length()).equalsIgnoreCase(??
- ????????????????????????res_string))?{??
- ????????????????????return?true;?//?增加通配符比較??
- ????????????????}??
- ????????????}??
- ????????????//?分割url與參數(shù)??
- ????????????String[]?spw?=?res_string.split("\\?");?//?用"\\?"?轉(zhuǎn)義后即可得到正確的結(jié)??
- ????????????if?(!url.equalsIgnoreCase(spw[0]))?{??
- ????????????????match?=?false;??
- ????????????}??
- ????????????if?(match?&&?spw.length?>?1)?{??
- ????????????????String[]?spa?=?spw[1].split("\\&");?//?分拆各參數(shù)??
- ????????????????for?(int?j?=?0;?j?<?spa.length;?j++)?{??
- ????????????????????String[]?spe?=?spa[j].split("=");?//?分拆鍵與值??
- ????????????????????String?key?=?spe[0];??
- ????????????????????String?value?=?"";??
- ????????????????????if?(spe.length?>?1)?{??
- ????????????????????????value?=?spe[1].trim();??
- ????????????????????}??
- ??
- ????????????????????//?輪詢??
- ????????????????????String[]?values?=?(String[])?reqmap.get(key);??
- ????????????????????if?(values?!=?null)?{??
- ????????????????????????for?(int?k?=?0;?k?<?values.length;?k++)?{??
- ????????????????????????????if?(value.equalsIgnoreCase(values[k]))?{??
- ????????????????????????????????match?=?true;??
- ????????????????????????????????break;??
- ????????????????????????????}??
- ????????????????????????????match?=?false;??
- ????????????????????????}??
- ????????????????????????if?(!match)?{??
- ????????????????????????????break;??
- ????????????????????????}??
- ????????????????????}??
- ????????????????}??
- ??
- ????????????}??
- ??
- ????????????if?(match)?{??
- ????????????????break;??
- ????????????}??
- ????????}??
- ????????return?match;??
- ????}??
- ??
- ????public?static?void?main(String[]?args)?{??
- ????????UrlFilter?filter?=?new?UrlFilter();??
- ????????String?url?=?"/baseProd/product.do";??
- ??
- ????????Map?reqmap?=?new?HashMap();??
- ????????//?當(dāng)前請求productline參數(shù)是11,12??
- ????????reqmap.put("productline",?new?String[]?{?"11",?"12"?});??
- ??
- ????????String?str;??
- ????????Set?royurl?=?new?HashSet();??
- ??
- ????????//?和授權(quán)的的url根本不同,false??
- ????????royurl.add("/user.do?a=1&b=2");??
- ????????System.out.println("match?false:"?+?filter.pass(royurl,?url,?reqmap));??
- ????????//?授權(quán)的請求參數(shù)13,14時?false??
- ????????royurl.add("/baseProd/product.do?productline=13&productline=14");??
- ????????System.out.println("match?false:"?+?filter.pass(royurl,?url,?reqmap));??
- ????????//?授權(quán)的請求參數(shù)11,13時?false??
- ????????royurl.add("/baseProd/product.do?productline=11&productline=13");??
- ????????System.out.println("match?false:"?+?filter.pass(royurl,?url,?reqmap));??
- ??
- ????????//?授權(quán)的請求參數(shù)11時?true??
- ????????royurl.add("/baseProd/product.do?productline=11");??
- ????????System.out.println("match?true:"?+?filter.pass(royurl,?url,?reqmap));??
- ??
- ????????//?參數(shù)的不論順序?true??
- ????????royurl.add("/baseProd/product.do?productline=12&productline=11");??
- ????????System.out.println("match?true:"?+?filter.pass(royurl,?url,?reqmap));??
- ??
- ????????royurl.clear();??
- ????????//?支持?"*"?號作通配符?true??
- ????????royurl.add("/baseProd/product.do*");??
- ????????System.out.println("match?ture:"?+?filter.pass(royurl,?url,?reqmap));??
- ??
- ????}??
- ??
- }??
- public?class?LoginUser?{??
- ????private?String?name;??
- ??????
- ????//用戶的授權(quán)url集合,如"/product.do?line=1&singer=2","/menu.do?son=1&son=2&son=3","/job.do*"??
- ????private?Set?resStrings;??
- ??
- ????public?String?getName()?{??
- ????????return?name;??
- ????}??
- ??
- ????public?void?setName(String?name)?{??
- ????????this.name?=?name;??
- ????}??
- ??
- ????public?Set?getResStrings()?{??
- ????????return?resStrings;??
- ????}??
- ??
- ????public?void?setResStrings(Set?resStrings)?{??
- ????????this.resStrings?=?resStrings;??
- ????}??
- ??????
- ??????
- }?
http://wiki.springside.org.cn/display/springside/Acegi+Reference
RBAC初學(xué)筆記
什么是RBAC?
RBAC就是Role-Based Access Control,基于角色的訪問控制。角色訪問控制(RBAC)引入了Role的概念,目的是為了隔離User(即動作主體,Subject)與Privilege(權(quán)限,表示對Resource的一個操作,即Operation+Resource),更符合企業(yè)的用戶、組織、數(shù)據(jù)和應(yīng)用特征。
RBAC的關(guān)注點在于Role與user,Role與privilege的關(guān)系,也就是User Assignment與Permission Assignment的關(guān)系。
RBAC有以下優(yōu)點:
1、減少授權(quán)管理的復(fù)雜性,降低管理開銷
2、靈活的支持企業(yè)的安全策略,對企業(yè)的變化有很大的伸縮性
解決復(fù)雜的權(quán)限管理問題的過程可以抽象概括為:判斷【Who是否可以對What進(jìn)行How的訪問操作(Operator)】這個邏輯表達(dá)式的值是否為True的求解過程。
RBAC中的幾個重要概念:
l???????? Who:權(quán)限的擁有者或主體。典型的有Principal、User、Group、Role、Actor等等。跟授權(quán)有關(guān)系的實體就只有角色(Role)和用戶(User)。譬如:業(yè)務(wù)經(jīng)理(Role),張三(User)
Role:作為一個用戶(User)與權(quán)限(Privilege)的代理層,解耦了權(quán)限和用戶的關(guān)系,所有的授權(quán)應(yīng)該給予Role而不是直接給User或Group。基于角色的訪問控制方法的思想就是把對用戶的授權(quán)分成兩部份,用角色來充當(dāng)用戶行駛權(quán)限的中介。角色是一組訪問權(quán)限的集合,一個用戶可以是很多角色的成員,一個角色也可以有很多個權(quán)限,而一個權(quán)限也可以重復(fù)配置于多個角色。
User:用戶就是一個可以獨立訪問計算機系統(tǒng)中的數(shù)據(jù)或者用數(shù)據(jù)表示的其它資源的主體,我們用USERS表示一個用戶集合。用戶在一般情況下是指人。
Group:是一組相關(guān)user的集合。User從group繼承出來,也就具有了該group的角色權(quán)限。
個人覺得可以這么認(rèn)為,role是抽象化了的user或group。
l???????? What:權(quán)限針對的資源(Resource)(包括資源類別(the type of Resource)和資源實例(the instance of Resource))。譬如:報表。
粗粒度:表示類別級,即僅考慮對象的類別(the type of object),不考慮對象的某個特定實例。比如,用戶管理中,創(chuàng)建、刪除,對所有的用戶都一視同仁,并不區(qū)分操作的具體對象實例。
細(xì)粒度:表示實例級,即需要考慮具體對象的實例(the instance of object),當(dāng)然,細(xì)粒度是在考慮粗粒度的對象類別之后才再考慮特定實例。比如,合同管理中,列表、刪除,需要區(qū)分該合同實例是否為當(dāng)前用戶所創(chuàng)建。
l???????? How:亦作action,表示某種訪問方法(亦請參考Operator條目解釋)。譬如:刪除。
l? Operator:操作。表示施加于What的How動作。是一種Resource Related的概念,單獨的How動作是沒有實際意義的,譬如:刪除;只有與具體資源結(jié)合在一起才有意義,譬如:刪除報表。
下面的圖展示了user,group,role,how的關(guān)系
權(quán)限系統(tǒng)的核心由以下三部分構(gòu)成:
1.????? 創(chuàng)造權(quán)限
2.?????? 分配權(quán)限
3.?????? 使用權(quán)限
系統(tǒng)各部分的主要參與者對照如下:
1.創(chuàng)造權(quán)限 - Programer創(chuàng)造,
2.分配權(quán)限 - Administrator 分配,
3.使用權(quán)限– User
- Programer 向權(quán)限系統(tǒng)提供 Operator = Privilege + Resource
- Administrator 利用 Operator 這個基本元素,來創(chuàng)造他理想中的權(quán)限模型。
如,創(chuàng)建角色,創(chuàng)建用戶組,給用戶組分配用戶,將用戶組與角色關(guān)聯(lián)等等...
這些操作都是由 Administrator 來完成的. - User 使用 Administrator 分配給的權(quán)限去使用各個系統(tǒng)。
用最新的appfuse1.9.3版本!
到:http"://appfuse.org/下載appfuse1.93
用idea打開
只需要修改properties.xml中的
????<property?name="database.jar"?location="${mysql.jar}"/>
????<property?name="database.type"?value="mysql"/>
????<property?name="database.name"?value="appfuse"/>
????<property?name="database.host"?value="localhost"/>
????<property?name="database.username"?value="root"/>
????<property?name="database.password"?value="root"/>
把其中的localhost修改成實際的ip就ok了
比如說是:192.169.0.1:3306,注意一定要加上端口號!
然后在ant中運行相關(guān)的任務(wù):
我這里的情況是:
建數(shù)據(jù)庫表和數(shù)據(jù)的不走是
運行 db-prepare--》db-create--》db-load,這樣數(shù)據(jù)就建上了
然后deploy,在ie中運行appfuse就ok了!
?2??*?Copyright?(c)?2006?Your?Corporation.?All?Rights?Reserved.
?3??*/
?4?package?liuxuan;
?5?
?6?/**
?7??*?Created?by?IntelliJ?IDEA.
?8??*?User:?Administrator
?9??*?Date:?2006-7-26
10??*?Time:?15:33:49
11??*?To?change?this?template?use?File?|?Settings?|?File?Templates.
12??*/
13?import?org.htmlparser.Node;
14?import?org.htmlparser.Parser;
15?import?org.htmlparser.http.ConnectionManager;
16?import?org.htmlparser.tags.LinkTag;
17?import?org.htmlparser.util.ParserException;
18?import?org.htmlparser.visitors.ObjectFindingVisitor;
19?
20?import?java.sql.Statement;
21?import?java.sql.DriverManager;
22?import?java.sql.Connection;
23?import?java.sql.SQLException;
24?
25?public?class?LinkDemo
26?{
27?????public?static?void?main?(String[]?args)?throws?ParserException,?SQLException
28?????{
29?????????ConnectionManager?cn?=?new?ConnectionManager();
30?????????cn.setProxyHost("10.75.1.38");
31?????????cn.setProxyPort(80);
32?????????Parser.setConnectionManager(cn);
33?????????Parser?parser;
34?????????//parser.s
35?????????String[]?pyurl?=?new?String[2]?;
36?
37?????????pyurl[0]="http://www.google.cn/search?num=100&hl=zh-CN&newwindow=1&q=%E6%BF%AE%E9%98%B3&btnG=%E6%90%9C%E7%B4%A2&meta=cr%3DcountryCN";
38?????????pyurl[1]="http://www.google.cn/search?q=%E6%BF%AE%E9%98%B3&num=100&hl=zh-CN&lr=&cr=countryCN&newwindow=1&start=100&sa=N";
39?????????for?(int?j=0;j<pyurl.length;j++)?{
40?????????????parser?=?new?Parser?(pyurl[j]);
41?????????????ObjectFindingVisitor?visitor?=?new?ObjectFindingVisitor?(LinkTag.class);
42?????????????parser.visitAllNodesWith?(visitor);
43?????????????Node[]?links?=?visitor.getTags?();
44?????????????String?sql;
45?????????????????try?{
46?????????????????????????Class.forName("com.mysql.jdbc.Driver");
47?????????????????????}?catch?(ClassNotFoundException?e)?{
48?????????????????????????e.printStackTrace();??//To?change?body?of?catch?statement?use?File?|?Settings?|?File?Templates.
49?????????????????????}
50?????????????????????Connection?conn?=?null;
51?????????????????????try?{
52?????????????????????????conn?=?DriverManager.getConnection("jdbc:mysql://localhost:3306/crawdb",?"root",?"root");
53?????????????????????}?catch?(SQLException?e)?{
54?????????????????????????e.printStackTrace();??//To?change?body?of?catch?statement?use?File?|?Settings?|?File?Templates.
55?????????????????????}
56??????????????Statement?stmt?=?conn.createStatement();
57?????????????for?(int?i?=?0;?i?<?links.length;?i++)
58?????????????{
59?????????????????????sql="";
60?????????????????LinkTag?linkTag?=?(LinkTag)links[i];
61?????????????????if?(linkTag.getLink().indexOf("cache")<0?&&??linkTag.getLink().indexOf("google")<0?&&linkTag.getLinkText().indexOf("濮陽")>0)??{
62?
63?
64???????????????????????sql="insert?into?urls(name,note,url)?values('"+linkTag.getLinkText?()+"','"+"lixuan"+"','"+linkTag.getLink?()+"')";
65???????????????????????stmt.executeUpdate(sql);
66?????????????????????????//rs.close();
67?
68?????????????????????System.out.print?("\""?+?linkTag.getLinkText?()?+?"\"?=>?");
69?????????????????System.out.println?(linkTag.getLink?());
70?????????????????}
71?????????????}
72??????????????stmt.close();
73??????????????conn.close();
74?????????}
75?????}
76?
77?}
78?
- I use nutch to crawl the intranet.but you know ,the cache.jsp have mang problem (X).Because I filter the gif|jgf and so on
then I use ORO replace the html content use my customer pif
Code:?1????String?sRegexpSrc="src\\s*=\\s*\"([\\.]*)/([a-z]*)/([^\"]+)";
?2????String?sRegxpBackground?="background\\s*=\\s*\"([.]*)/([a-z]*)/([^\"]+)";
?3????String?sAdd?=?"";
?4????String?sNewContent="";
?5????PatternCompiler?compiler?=?new?Perl5Compiler();
?6????Pattern?pattern?=?null,pattern1?=?null?;
?7????try
{
?8????????pattern?=?compiler.compile(sRegexpSrc,Perl5Compiler.CASE_INSENSITIVE_MASK);
?9????????pattern1?=?compiler.compile(sRegxpBackground,Perl5Compiler.CASE_INSENSITIVE_MASK);
10????}catch?(MalformedPatternException?e)
{
11????????
12????????e.printStackTrace();
13????}
14????PatternMatcher?matcher?=?new?Perl5Matcher();
15
16if?(matcher.contains(content,?pattern))
{
17????????????????????MatchResult?result?=?matcher.getMatch();
18????????????????????//System.out.println(result.toString());
19????????????????????sAdd?=?result.group(1)+"/"+result.group(2)+"/"+result.group(3);
20????????????????????//System.out.println("sAdd=?"+sAdd);
21????????????????????sNewContent=content.replaceAll(sAdd,"\\img\\liuxuan");
22????????????????????//System.out.println("FinalString="+sTest.replaceAll(sAdd,"/img/liuxuan.png"));
23????????????//System.out.print("sTest=?"+result.group(1)+"/"+result.group(2));
24????????}else
{
25????????????//System.out.print("Can't?find?the?String?");
26
27????????}