亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Apache shiro的簡(jiǎn)單介紹與使用教程(與spring整合使用)

 更新時(shí)間:2017年10月09日 09:08:45   作者:高壓鍋里的小白  
Apache Shiro是一個(gè)強(qiáng)大而靈活的開(kāi)源安全框架,它能夠干凈利落地處理身份認(rèn)證,授權(quán),企業(yè)會(huì)話管理和加密這篇文章給大家介紹了Apache shiro的簡(jiǎn)單介紹與使用教程(與spring整合使用),感興趣的朋友一起看看吧

apache shiro框架簡(jiǎn)介

  Apache Shiro是一個(gè)強(qiáng)大而靈活的開(kāi)源安全框架,它能夠干凈利落地處理身份認(rèn)證,授權(quán),企業(yè)會(huì)話管理和加密?,F(xiàn)在,使用Apache Shiro的人越來(lái)越多,因?yàn)樗喈?dāng)簡(jiǎn)單,相比比Spring Security,Shiro可能沒(méi)有Spring Security那么多強(qiáng)大的功能,但是在實(shí)際工作時(shí)可能并不需要那么復(fù)雜的東西,所以使用簡(jiǎn)單的Shiro就足夠了。

  以下是你可以用 Apache Shiro所做的事情:

  Shiro的4大核心部分——身份驗(yàn)證,授權(quán),會(huì)話管理和加密

     Authentication:身份驗(yàn)證,簡(jiǎn)稱“登錄”。

     Authorization:授權(quán),給用戶分配角色或者權(quán)限資源

     Session Management:用戶session管理器,可以讓CS程序也使用session來(lái)控制權(quán)限

     Cryptography:把JDK中復(fù)雜的密碼加密方式進(jìn)行封裝。

  除了以上功能,shiro還提供很多擴(kuò)展   

  Web Support:主要針對(duì)web應(yīng)用提供一些常用功能。

  Caching:緩存可以使應(yīng)用程序運(yùn)行更有效率。

  Concurrency:多線程相關(guān)功能。

  Testing:幫助我們進(jìn)行測(cè)試相關(guān)功能

  Run As:一個(gè)允許用戶假設(shè)為另一個(gè)用戶身份(如果允許)的功能,有時(shí)候在管理腳本很有用。

  Remember Me:記住用戶身份,提供類似購(gòu)物車(chē)功能。

  shiro框架認(rèn)證流程

  Application Code:應(yīng)用程序代碼,由開(kāi)發(fā)人員負(fù)責(zé)開(kāi)發(fā)的

  Subject:框架提供的接口,是與程序進(jìn)行交互的對(duì)象,可以是人也可以是服務(wù)或者其他,通常就理解為用戶。所有Subject 實(shí)例都必須綁定到一個(gè)SecurityManager上。我們與一個(gè) Subject 交互,運(yùn)行時(shí)shiro會(huì)自動(dòng)轉(zhuǎn)化為與 SecurityManager交互的特定 subject的交互。

  SecurityManager:框架提供的接口,是 Shiro的核心,代表安全管理器對(duì)象。初始化時(shí)協(xié)調(diào)各個(gè)模塊運(yùn)行。然而,一旦 SecurityManager協(xié)調(diào)完畢,SecurityManager 會(huì)被單獨(dú)留下,且我們只需要去操作Subject即可,無(wú)需操作SecurityManager 。 但是我們得知道,當(dāng)我們正與一個(gè) Subject 進(jìn)行交互時(shí),實(shí)質(zhì)上是 SecurityManager在處理 Subject 安全操作。

  Realm:可以開(kāi)發(fā)人員編寫(xiě),框架也提供一些。Realms在 Shiro中作為應(yīng)用程序和安全數(shù)據(jù)之間的“橋梁”或“連接器”。他獲取安全數(shù)據(jù)來(lái)判斷subject是否能夠登錄,subject擁有什么權(quán)限。他有點(diǎn)類似DAO。在配置realms時(shí),需要至少一個(gè)realm。而且Shiro提供了一些常用的 Realms來(lái)連接數(shù)據(jù)源,如LDAP數(shù)據(jù)源的JndiLdapRealm,JDBC數(shù)據(jù)源的JdbcRealm,ini文件數(shù)據(jù)源的IniRealm,properties文件數(shù)據(jù)源的PropertiesRealm,等等。我們也可以插入自己的 Realm實(shí)現(xiàn)來(lái)代表自定義的數(shù)據(jù)源。 像其他組件一樣,Realms也是由SecurityManager控制。

  更詳細(xì)的圖

  下面就開(kāi)始shiro與SSM工程的整合使用

  下載地址:http://shiro.apache.org/download.html

  下載下來(lái)這兩個(gè)個(gè)文件,一個(gè)jar包,一個(gè)源碼文件

  首先,第一步,將jar包導(dǎo)入到工程中

  然后,第二步,在web.xml中配置spring框架提供的用于整合shiro框架的過(guò)濾器(一定要放到springmvc或struts框架過(guò)濾器的前面,為了保險(xiǎn)起見(jiàn),放到最上面就好了)

<!--配置過(guò)濾器,用于整合Shiro-->
<filter>
  <filter-name>shiroFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>shiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

  第三步,在spring配置文件中配置bean,id為shiroFilter

<!-- 配置shiro框架的過(guò)濾器工廠bean -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/index.jsp"/>
  <property name="successUrl" value=""/>
  <property name="unauthorizedUrl" value="/noPrivilegeUI.jsp"/>
  <!-- 指定URL級(jí)別攔截策略 -->
  <property name="filterChainDefinitions">
    <value>
      /script/** = anon
      /style/** = anon
      /index.jsp* = anon
      /noPrivilegeUI.jsp* = anon
      /user/login = anon
       /role/findAllRoleList = perms["角色管理"]
      /** = authc
    </value>
  </property>
</bean>  

  securityManager:這個(gè)屬性是必須的。

  loginUrl :沒(méi)有登錄的用戶請(qǐng)求需要登錄的頁(yè)面時(shí)自動(dòng)跳轉(zhuǎn)到登錄頁(yè)面,不是必須的屬性,不輸入地址的話會(huì)自動(dòng)尋找項(xiàng)目web項(xiàng)目的根目錄下的”/login.jsp”頁(yè)面。

  successUrl :登錄成功默認(rèn)跳轉(zhuǎn)頁(yè)面,可以不配置,不配置則跳轉(zhuǎn)至”/”。如果登陸前點(diǎn)擊的一個(gè)需要登錄的頁(yè)面,則在登錄自動(dòng)跳轉(zhuǎn)到那個(gè)需要登錄的頁(yè)面。不跳轉(zhuǎn)到此。

  unauthorizedUrl :沒(méi)有權(quán)限默認(rèn)跳轉(zhuǎn)的頁(yè)面。

  anon: 例子/admins/** = anon 沒(méi)有參數(shù),表示可以匿名使用(需要認(rèn)證(登錄))。

  authc : 例如/admins/user/** = authc 表示需要認(rèn)證(登錄)才能使用,沒(méi)有參數(shù)

  roles:例子/admins/user/** = roles[admin], 參數(shù)可以寫(xiě)多個(gè),多個(gè)時(shí)必須加上引號(hào),并且參數(shù)之間用逗號(hào)分割,當(dāng)有多個(gè)參數(shù)時(shí),例如admins/user/** = roles["admin,guest"], 每個(gè)參數(shù)通過(guò)才算通過(guò),相當(dāng)于hasAllRoles()方法。

  perms:例子/admins/user/** = perms[user:add:*], 參數(shù)可以寫(xiě)多個(gè),多個(gè)時(shí)必須加上引號(hào),并且參數(shù)之間用逗號(hào)分割,例如/admins/user/** = perms["user:add:*,user:modify:*"],當(dāng)有多個(gè)參數(shù)時(shí)必須每個(gè)參數(shù)都通過(guò)才通過(guò),想當(dāng)于  isPermitedAll()方法。

  Rest:例子/admins/user/** = rest[user];根據(jù)請(qǐng)求的方法,相當(dāng)于/admins/user/** = perms[user:method] ;其中method為post,get,delete等。

  port:例子/admins/user/** = port[8081]; 當(dāng)請(qǐng)求的url的端口不是8081是跳轉(zhuǎn)到schemal://serverName:8081?queryString,其中schmal是協(xié)議http或https等,serverName是你訪問(wèn)的host,8081是url配置里port的端口,queryString

是你訪問(wèn)的url里的?后面的參數(shù)。

  authcBasic:例如/admins/user/** = authcBasic; 沒(méi)有參數(shù)表示httpBasic認(rèn)證

  ssl:例子/admins/user/** = ssl;沒(méi)有參數(shù),表示安全的url請(qǐng)求,協(xié)議為https

  user:例如/admins/user/** = user; 沒(méi)有參數(shù)表示必須存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查

  注:anon,authcBasic,auchc,user是認(rèn)證過(guò)濾器,

    perms,roles,ssl,rest,port是授權(quán)過(guò)濾器

  第四步:配置安全管理器

<!-- 配置安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"/>

  第五步:寫(xiě)一個(gè)login方法,使用shiro提供的方式進(jìn)行認(rèn)證操作

  這是我之前的login方法,以這種方法,shiro是不知道登錄驗(yàn)證通過(guò)了的,一直不通過(guò),所以我們要以shiro提供的認(rèn)證操作方式進(jìn)行登錄操作

/**
 * 登錄
 */
@RequestMapping("/login")
public String login(User user, HttpServletRequest request, Model model){
  HttpSession session = request.getSession();
  User newUser = userService.login(user);
  if(newUser != null){
    session.setAttribute("loginUser",newUser);
    return "home/home";
  }
  model.addAttribute("errorMessage","用戶名或者密碼不正確!");
  return "forward:/index.jsp";
}

   修改后的login方法

/**
 * 使用Shiro框架提供的方式進(jìn)行認(rèn)證登錄
 */
@RequestMapping("/login")
public String login(User user, HttpServletRequest request, Model model){
  HttpSession session = request.getSession();
  //使用Shiro框架提供的方式進(jìn)行認(rèn)證
  Subject subject = SecurityUtils.getSubject(); //獲得當(dāng)前登錄用戶對(duì)象,現(xiàn)在狀態(tài)為 “未認(rèn)證”
  //用戶名密碼令牌
  AuthenticationToken token = new UsernamePasswordToken(user.getLoginName(), MD5Utils.md5(user.getPassword()));
  try{
    subject.login(token); //執(zhí)行你自定義的Realm
    User user1 = (User) subject.getPrincipal();
    session.setAttribute("loginUser",user1);
    return "home/home";
  }catch(UnknownAccountException e){
    e.printStackTrace();
    model.addAttribute("errorMessage","此用戶名不存在!");
  }catch(IncorrectCredentialsException e){
    e.printStackTrace();
    model.addAttribute("errorMessage","密碼不正確!");
  }catch(Exception e){
    e.printStackTrace();
  }
  return "forward:/index.jsp";
}

  第六步:自定義realm,并注入給安全管理器 

  創(chuàng)建一個(gè)UserRealm類,繼承AuthorizingRealm這個(gè)類 

public class UserRealm extends AuthorizingRealm{
  @Autowired
  private UserDao userDao;
   //認(rèn)證方法
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    System.out.println("realm中的認(rèn)證方法執(zhí)行了。。。。");
    UsernamePasswordToken myToken = (UsernamePasswordToken) token;
    String loginName = myToken.getUsername();
    //根據(jù)用戶名查詢數(shù)據(jù)庫(kù)中的用戶,這個(gè)方法是自己寫(xiě)的
    User user = userDao.findUserByLoginName(loginName);
    if(user == null){
      //用戶名不存在
      return null;
    }
    //如果能查詢到,再由框架比對(duì)數(shù)據(jù)庫(kù)中查詢到的密碼和頁(yè)面提交的密碼是否一致
    AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
    return info;
  }
   //授權(quán)方法
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    return null;
  }
}

  將自定義realm注入給安全管理器

<!-- 配置安全管理器 -->
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- 注入realm -->
    <property name="realm" ref="userRealm"/>
  </bean>
  <!-- 注冊(cè)自定義realm -->
  <bean id="userRealm" class="com.demo.privilege.service.realm.UserRealm"/>

  到這里程序就可以正常運(yùn)行了,登錄后進(jìn)入首頁(yè)

  但是點(diǎn)擊角色管理,會(huì)進(jìn)入沒(méi)有權(quán)限的頁(yè)面

  這是因?yàn)槲以趕pring配置文件中配置了   /role/findAllRoleList = perms["角色管理"],而我還沒(méi)有給當(dāng)前用戶授權(quán),所以當(dāng)前用戶沒(méi)有權(quán)限訪問(wèn)此路徑

  所以要給該用戶授權(quán),在UserRealm類中,編寫(xiě)授權(quán)方法

//授權(quán)方法
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    User user = (User) principals.getPrimaryPrincipal();
    for (Role role : user.getRoles()){
      for (Privilege privilege : role.getPrivileges()){
        info.addStringPermission(privilege.getName());
      }
    }
    return info;
  }

  這樣,就可以正常訪問(wèn)了,這個(gè)授權(quán)方法是在訪問(wèn)/role/findAllRoleList這個(gè)路徑時(shí),shiro框架自動(dòng)調(diào)用的

  我們之前進(jìn)行權(quán)限控制是在spring配置文件中配置了   /role/findAllRoleList = perms["角色管理"] ,現(xiàn)在介紹另一種方式,也是我比較喜歡的方式, 使用注解方式進(jìn)行權(quán)限控制

   使用shiro的方法注解方式權(quán)限控制

  第一步:在springmvc配置文件中開(kāi)啟shiro注解支持(注意:springmvc框架,放到springmvc配置文件中,struts放到spring配置文件中) 

<!-- 保證實(shí)現(xiàn)了Shiro內(nèi)部lifecycle函數(shù)的bean執(zhí)行 --> 
  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
  <!-- 開(kāi)啟shiro框架注解支持 -->
  <!-- 自動(dòng)代理 -->
  <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
    <!-- value必須設(shè)置為true使用cglib方式為對(duì)象創(chuàng)建代理對(duì)象,
      默認(rèn)為false,設(shè)為false,就是使用JDK方式為對(duì)象創(chuàng)建代理對(duì)象,程序會(huì)出錯(cuò) --> 
    <property name="proxyTargetClass" value="true"/>
  </bean>
  <!-- 配置shiro框架提供的切面類,用于創(chuàng)建代理對(duì)象 -->
  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>

  第二步:在Controller的方法上使用shiro注解------ @RequiresPermissions("") 執(zhí)行這個(gè)方法必須有相應(yīng)的權(quán)限  

 /**
   * 查詢崗位列表
   */
  @RequiresPermissions("角色列表") //執(zhí)行這個(gè)方法必須有角色列表這個(gè)權(quán)限
  @RequestMapping("/findAllRoleList")
  public String findAllRoleList(Model model){
    List<Role> roleList = roleService.findAllRoleList();
    model.addAttribute("roleList",roleList);
    return "role/list";
  }

  @RequiresAuthentication

    驗(yàn)證用戶是否登錄,等同于方法subject.isAuthenticated() 結(jié)果為true時(shí)。

  @ RequiresUser

    驗(yàn)證用戶是否被記憶,user有兩種含義:

    一種是成功登錄的(subject.isAuthenticated() 結(jié)果為true);

    另外一種是被記憶的( subject.isRemembered()結(jié)果為true)。

  @ RequiresGuest

    驗(yàn)證是否是一個(gè)guest的請(qǐng)求,與@ RequiresUser完全相反。

           換言之,RequiresUser  == ! RequiresGuest 。

      此時(shí)subject.getPrincipal() 結(jié)果為null.

  @ RequiresRoles

    例如:

@RequiresRoles("aRoleName");
            void someMethod();

    如果subject中有aRoleName角色才可以訪問(wèn)方法someMethod。如果沒(méi)有這個(gè)權(quán)限則會(huì)拋出異常AuthorizationException。

  @RequiresPermissions

    例如:

@RequiresPermissions( {"file:read", "write:aFile.txt"} )
            void someMethod();

    要求subject中必須同時(shí)含有file:read和write:aFile.txt的權(quán)限才能執(zhí)行方法someMethod()。否則拋出異常AuthorizationException。

   注解方式的權(quán)限控制就完成了,但這種方式?jīng)]有權(quán)限時(shí)不會(huì)自動(dòng)跳轉(zhuǎn)到?jīng)]有權(quán)限的頁(yè)面,而是直接把異常拋到頁(yè)面了,所以我們要配置一個(gè)全局的異常處理

  第三步:在springmvc配置文件中,進(jìn)行如下配置,配置全局異常捕獲,當(dāng)shiro框架拋出權(quán)限不足異常時(shí),跳轉(zhuǎn)到權(quán)限不足提示頁(yè)面

<!-- 全局異常處理 -->  
  <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
    <property name="exceptionMappings"> 
      <props> 
        <prop key="org.apache.shiro.authz.UnauthorizedException">redirect:/noPrivilegeUI.jsp</prop> 
      </props> 
    </property> 
  </bean> 

  使用shiro提供的頁(yè)面標(biāo)簽方式權(quán)限控制

  最后,說(shuō)一說(shuō)shiro提供的頁(yè)面標(biāo)簽  

  第一步:在jsp頁(yè)面中引入shiro的標(biāo)簽庫(kù)

<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>

  第二步:使用shiro的標(biāo)簽控制頁(yè)面元素展示

  這樣,一個(gè)shiro入門(mén)程序就完成了。

總結(jié)

以上所述是小編給大家介紹的Apache shiro的簡(jiǎn)單介紹與使用教程(與spring整合使用),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 淺談ubuntu執(zhí)行.sh文件幾種方式區(qū)別

    淺談ubuntu執(zhí)行.sh文件幾種方式區(qū)別

    這篇文章主要介紹了淺談ubuntu執(zhí)行.sh文件幾種方式區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Apache 獲取真實(shí)ip的配置的實(shí)現(xiàn)方法

    Apache 獲取真實(shí)ip的配置的實(shí)現(xiàn)方法

    這篇文章主要介紹了Apache 獲取真實(shí)ip的配置的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • 檢測(cè)ip和port是否可連接的方法

    檢測(cè)ip和port是否可連接的方法

    今天小編就為大家分享一篇檢測(cè)ip和port是否可連接的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Linux中用rename命令批量替換文件名方法實(shí)例

    Linux中用rename命令批量替換文件名方法實(shí)例

    這篇文章主要介紹了Linux中用rename命令批量替換文件名的方法,文中詳細(xì)介紹了在Debian或者Ubuntu下批量替換文件名的語(yǔ)法和實(shí)例代碼,對(duì)大家具有一定的參考價(jià)值,需要的朋友可以們下面來(lái)一起看看吧。
    2017-04-04
  • 在CentOS 7下使用yum配置MySQL源并安裝MySQL

    在CentOS 7下使用yum配置MySQL源并安裝MySQL

    這篇文章主要介紹了CentOS 7.0下使用yum安裝mysql的方法詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • jmeter 在linux服務(wù)器的安裝和運(yùn)行教程圖解

    jmeter 在linux服務(wù)器的安裝和運(yùn)行教程圖解

    本文通過(guò)圖文并茂的形式給大家介紹了jmeter 在linux服務(wù)器的安裝和運(yùn)行的,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • CentOS6.8中/英文環(huán)境切換教程圖解

    CentOS6.8中/英文環(huán)境切換教程圖解

    這篇文章主要介紹了CentOS6.8中/英文環(huán)境切換教程,本文只以中文切換為英文為例給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Linux 系統(tǒng)下安裝JDK1.8的教程詳解

    Linux 系統(tǒng)下安裝JDK1.8的教程詳解

    這篇文章主要介紹了Linux 系統(tǒng)下安裝JDK1.8的教程詳解,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • linux配置SSH全過(guò)程

    linux配置SSH全過(guò)程

    這篇文章主要介紹了linux配置SSH全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Ubuntu18.04(linux)安裝MySQL的方法步驟

    Ubuntu18.04(linux)安裝MySQL的方法步驟

    本篇文章主要介紹了Ubuntu18.04(linux)安裝MySQL的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05

最新評(píng)論