菜園子

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            7 Posts :: 1 Stories :: 31 Comments :: 0 Trackbacks

          Shiro權(quán)限框架

          開(kāi)發(fā)系統(tǒng)中,少不了權(quán)限,目前java里的權(quán)限框架有SpringSecurity和Shiro(以前叫做jsecurity),對(duì)于SpringSecurity:功能太過(guò)強(qiáng)大以至于功能比較分散,使用起來(lái)也比較復(fù)雜,跟Spring結(jié)合的比較好。對(duì)于初學(xué)Spring Security者來(lái)說(shuō),曲線(xiàn)還是較大,需要深入學(xué)習(xí)其源碼和框架,配置起來(lái)也需要費(fèi)比較大的力氣,擴(kuò)展性也不是特別強(qiáng)。

          對(duì)于新秀Shiro來(lái)說(shuō),好評(píng)還是比較多的,使用起來(lái)比較簡(jiǎn)單,功能也足夠強(qiáng)大,擴(kuò)展性也較好。聽(tīng)說(shuō)連Spring的官方都不用Spring Security,用的是Shiro,足見(jiàn)Shiro的優(yōu)秀。網(wǎng)上找到兩篇介紹:http://www.infoq.com/cn/articles/apache-shiro http://www.ibm.com/developerworks/cn/opensource/os-cn-shiro/,官網(wǎng)http://shiro.apache.org/ ,使用和配置起來(lái)還是比較簡(jiǎn)單。下面只是簡(jiǎn)單介紹下我們是如何配置和使用Shiro的(暫時(shí)只用到了Shiro的一部分,沒(méi)有配置shiro.ini文件)。

          首先是添加過(guò)濾器,在web.xml中:

          <filter>

          <filter-name>shiroFilter</filter-name>

          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

          <init-param>

                      <param-name>targetFilterLifecycle</param-name>

                      <param-value>true</param-value>

               </init-param>

          </filter>    

          <filter-mapping>

          <filter-name>shiroFilter</filter-name>

          <url-pattern>/*</url-pattern>

          </filter-mapping>

          權(quán)限的認(rèn)證類(lèi):

          public class ShiroDbRealm extends AuthorizingRealm {

              @Inject

              private UserService userService ;

              

              /**

           * 認(rèn)證回調(diào)函數(shù),登錄時(shí)調(diào)用.

           */

          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) 
          throws AuthenticationException {

          UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

          User useruserService.getUserByUserId(token.getUsername());

          if (user!= null) {  

              return new SimpleAuthenticationInfo(user.getUserId(), user.getUserId(), getName());

          else {

          return null;

          }

          }

          /**

           * 授權(quán)查詢(xún)回調(diào)函數(shù), 進(jìn)行鑒權(quán)但緩存中無(wú)用戶(hù)的授權(quán)信息時(shí)調(diào)用.

           */

          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

          String loginName = (String) principals.fromRealm(getName()).iterator().next();

          User useruserService.getUserByUserId(loginName);

          if (user != null) {

          SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

          info.addStringPermission("common-user");

          return info;

          else {

          return null;

          }

          }

          }

          Spring的配置文件:

          <?xml version="1.0" encoding="UTF-8"?>

          <beans >

          <description>Shiro Configuration</description>

          <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

          <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

          <property name="realm" ref="shiroDbRealm" />

          </bean>

          <bean id="shiroDbRealm" class="com.company.service.common.shiro.ShiroDbRealm" />

              <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

                  <property name="securityManager" ref="securityManager"/>

                  <property name="loginUrl" value="/common/security/login" />

                  <property name="successUrl" value="/common/security/welcome" />

                  <property name="unauthorizedUrl" value="/common/security/unauthorized"/>

                  <property name="filterChainDefinitions">

                      <value>

                          /resources/** = anon

                          /manageUsers = perms[user:manage]

                          /** = authc

                      </value>

                  </property>

              </bean>

          <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

              <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>

              <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

                  <property name="securityManager" ref="securityManager"/>

              </bean>

          </beans>

          登錄的Controller:

          @Controller

          @RequestMapping(value = "/common/security/*")

          public class SecurityController {

              @Inject

              private UserService userService;

              @RequestMapping(value = "/login")

              public String login(String loginName, String password,
          HttpServletResponse response, HttpServletRequest request) throws Exception {

                  User user = userService.getUserByLogin(loginName);

                      if (null != user) {

                          setLogin(loginInfoVO.getUserId(), loginInfoVO.getUserId());

                          return "redirect:/common/security/welcome";

                      } else {

                          return "redirect:/common/path?path=showLogin";

                      }

              };

              public static final void setLogin(String userId, String password) {

                  Subject currentUser = SecurityUtils.getSubject();

                  if (!currentUser.isAuthenticated()) {

                      //collect user principals and credentials in a gui specific manner 

                      //such as username/password html form, X509 certificate, OpenID, etc.

                      //We'll use the username/password example here since it is the most common.

                      //(do you know what movie this is from? ;)

                      UsernamePasswordToken token = new UsernamePasswordToken(userId, password);

                      //this is all you have to do to support 'remember me' (no config - built in!):

                      token.setRememberMe(true);

                      currentUser.login(token);

                  }

              };

              

              @RequestMapping(value="/logout")

              @ResponseBody

              public void logout(HttpServletRequest request){

                  Subject subject = SecurityUtils.getSubject();

                  if (subject != null) {           

                      subject.logout();

                  }

                  request.getSession().invalidate();

              };

          }

          注冊(cè)和獲取當(dāng)前登錄用戶(hù):

              public static final void setCurrentUser(User user) {

                  Subject currentUser = SecurityUtils.getSubject();

                  if (null != currentUser) {

                      Session session = currentUser.getSession();

                      if (null != session) {

                          session.setAttribute(Constants.CURRENT_USER, user);

                      }

                  }

              };

              public static final User getCurrentUser() {

                  Subject currentUser = SecurityUtils.getSubject();

                  if (null != currentUser) {

                      Session session = currentUser.getSession();

                      if (null != session) {

                          User user = (User) session.getAttribute(Constants.CURRENT_USER);

                          if(null != user){

                              return user;

                          }

          }

          }

              };

          需要的jar包有3個(gè):shiro-core.jar,shiro-spring.jar,shiro-web.jar。感覺(jué)shiro用起來(lái)比SpringSecurity簡(jiǎn)單很多。



          QQ:24889356
          posted on 2011-09-16 21:36 GhostZhang 閱讀(32448) 評(píng)論(14)  編輯  收藏

          Feedback

          # re: Shiro權(quán)限框架 2011-09-17 08:55 tb
          恩 比較不錯(cuò)   回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-17 17:20 rox
          正好在看appfuse和springside4的樣例,謝謝了。  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-17 22:59 wison
          我現(xiàn)在唯一還有疑問(wèn)的就是,這個(gè)數(shù)據(jù)庫(kù)表中的字段,怎么設(shè)計(jì)。怎么查詢(xún)出來(lái)。望樓主解釋。3Q  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-18 07:58 GhostZhang
          這個(gè)只是系統(tǒng)權(quán)限,不是業(yè)務(wù)權(quán)限。所以表設(shè)計(jì)的話(huà),我猜你指的是業(yè)務(wù)權(quán)限的表設(shè)計(jì)吧。shiro不涉及。  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-19 09:22 wison
          @GhostZhang
          嗯,我說(shuō)的是業(yè)務(wù)權(quán)限表的設(shè)計(jì),好吧,我們不談權(quán)限設(shè)置。僅僅談登錄,登錄總需要獲得帳號(hào)密碼,和數(shù)據(jù)庫(kù)中的比對(duì)吧。如何驗(yàn)證,不清楚是需要我們自己去寫(xiě)還是shiro已經(jīng)封裝好了。我僅僅是不清楚這個(gè)地方。3Q樓主。  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-19 14:27 GhostZhang
          @wison
          這個(gè)需要自己寫(xiě)。  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2011-09-20 09:22 wison
          @GhostZhang
          OK,3Q  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2012-02-29 22:50 唐文韜
          你好,我在整合shiro和spring的過(guò)程中,我只要給control加@RequiresAuthentication 類(lèi)似的這種注解,在項(xiàng)目啟動(dòng)的時(shí)候就報(bào)錯(cuò)
          Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
          at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)
          at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)
          at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
          at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
          at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
          at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
          ... 35 more

          可是當(dāng)我把cglib.jar的包加進(jìn)去的時(shí)候還是報(bào)錯(cuò),期待您的解答  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架[未登錄](méi) 2012-03-04 09:30 ghostzhang
          cglib-nodep-2.2.jar
          我用的是這個(gè),添加@RequiresAuthentication,啟動(dòng)沒(méi)問(wèn)題。  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2012-04-25 16:37 wgw
          @唐文韜

          <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
          <property name="proxyTargetClass" value="true" /> <!-- 和struts結(jié)合使用必須把該屬性設(shè)置為true,否則使用注解出錯(cuò) -->
          </bean>
          OK  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2014-03-11 13:09 JSON
          頁(yè)面怎么獲取session  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架[未登錄](méi) 2015-12-05 15:34 1
          1111  回復(fù)  更多評(píng)論
            

          # re: Shiro權(quán)限框架 2016-03-21 14:58 11
          32  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 延安市| 吴堡县| 南涧| 盐津县| 蒙自县| 南丹县| 三穗县| 泰兴市| 抚远县| 开平市| 磴口县| 偏关县| 安平县| 仙游县| 宁海县| 万安县| 中阳县| 五大连池市| 铜鼓县| 隆尧县| 嘉义县| 台湾省| 格尔木市| 阜康市| 德保县| 秀山| 英山县| 鄂尔多斯市| 宝兴县| 平阳县| 沈丘县| 错那县| 象山县| 夏邑县| 清远市| 宜良县| 水城县| 芦山县| 遂平县| 乐昌市| 郑州市|