激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java Apache Shiro安全框架快速開發詳解流程

Java Apache Shiro安全框架快速開發詳解流程

2022-03-02 00:51龍弟-idea Java教程

Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序

一、Shiro簡介:

Apache Shiro是一個Java的安全(權限)框架
Shiro 可以非常容易的開發出足夠好的應用,其不僅可以用在JavaSE環境,也可以用在JavaEE環境。Shiro可以完成,認證,授權,加密,會話管理,Web集成,緩存等。
官網地址:Apache Shiro | Simple. Java. Security.

Java Apache Shiro安全框架快速開發詳解流程

shiro功能:

Java Apache Shiro安全框架快速開發詳解流程

Authentication:身份認證、登錄,驗證用戶是不是擁有相應的身份;
Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限,即判斷用戶能否進行什么操作,如:驗證某個用戶是否擁有某個角色,或者細粒度的驗證某個用戶對某個資源是否具有某個權限!
Session Manager:會話管理,即用戶登錄后就是第一次會話,在沒有退出之前,它的所有信息都在會話中;會話可以是普通的JavaSE環境,也可以是Web環境;
Cryptography:加密,保護數據的安全性,如密碼加密存儲到數據庫中,而不是明文存儲;Web Support: Web支持,可以非常容易的集成到Web環境;
Caching:緩存,比如用戶登錄后,其用戶信息,擁有的角色、權限不必每次去查,這樣可以提高效率
Concurrency: Shiro支持多線程應用的并發驗證,即,如在一個線程中開啟另一個線程,能把權限自動的傳播過去
Testing:提供測試支持;
Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問;
Remember Me:記住我,這個是非常常見的功能,即一次登錄后,下次再來的話不用登錄了

Shiro架構(外部)

從外部來看Shiro,即從應用程序角度來觀察如何使用shiro完成工作:

Java Apache Shiro安全框架快速開發詳解流程

subject:應用代碼直接交互的對象是Subject,也就是說Shiro的對外API核心就是Subject,Subject代表了當前的用戶,這個用戶不一定是一個具體的人,與當前應用交互的任何東西都是Subject,如網絡爬蟲,機器人等,與Subject的所有交互都會委托給SecurityManager; Subject其實是一個門面,SecurityManageer才是實際的執行者
SecurityManager: 安全管理器,即所有與安全有關的操作都會與SercurityManager交互,并且它管理著所有的Subject,可以看出它是Shiro的核心,它負責與Shiro的其他組件進行交互,它相當于SpringMVC的
DispatcherServlet的角色
Realm: Shiro從Realm獲取安全數據((如用戶,角色,權限),就是說SecurityManager要驗證用戶身份,那么它需要從Realm 獲取相應的用戶進行比較,來確定用戶的身份是否合法;也需要從Realm得到用戶相應的角色、權限,進行驗證用戶的操作是否能夠進行,可以把Realm看成DataSource;

Shiro架構(內部)

Java Apache Shiro安全框架快速開發詳解流程

subject:任何可以與應用交互的'用戶';
Security Manager:相當于SpringMVC中的DispatcherServlet;是Shiro的心臟,所有具體的交互都通過Security Manager進行控制,它管理者所有的Subject,且負責進行認證,授權,會話,及緩存的管理.

Authenticator:負責Subject認證,是一個擴展點,可以自定義實現;可以使用認證策略(AuthenticationStrategy),即什么情況下算用戶認證通過了;
Authorizer: 授權器,即訪問控制器,用來決定主體是否有權限進行相應的操作;即控制著用戶能訪問應用中的那些功能;
Realm:可以有一個或者多個的realm,可以認為是安全實體數據源,即用于獲取安全實體的,可以用DBC實現,也可以是內存實現等等,由用戶提供;所以一般在應用中都需要實現自己的realm
SessionManager: 管理Session生命周期的組件,而Shiro并不僅僅可以用在Web環境,也可以用在普通的JavaSE環境中
CacheManager:緩存控制器,來管理如用戶,角色,權限等緩存的;因為這些數據基本上很少以受,成到緩存中后可以提高訪問的性能;
Cryptography:密碼模塊,Shiro提高了一些常見的加密組件用于密碼加密,解密等

 

二、快速入門

1.拷貝案例

1.按照官網提示找到 快速入門案例 GitHub地址:shiro/samples/quickstart/

Java Apache Shiro安全框架快速開發詳解流程

2.新建一個 Maven 工程,刪除其 src 目錄,將其作為父工程

3.在父工程中新建一個 Maven 模塊

4.復制快速入門案例 POM.xml 文件中的依賴

<dependencies>
      <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-core</artifactId>
          <version>1.4.1</version>
      </dependency>

      <!-- configure logging -->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <version>1.7.29</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.29</version>
      </dependency>
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>
  </dependencies>

5.把快速入門案例中的 resource 下的log4j.properties復制下來

6.復制一下shiro.ini文件

7.復制一下Quickstart.java文件

8.運行啟動Quickstart.java

Java Apache Shiro安全框架快速開發詳解流程

2.分析代碼

public class Quickstart {
  private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
  public static void main(String[] args) {
      //工廠模式,通過shiro.ini配置文件中的信息,生成一個工廠實例
      Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
      SecurityManager securityManager = factory.getInstance();
      SecurityUtils.setSecurityManager(securityManager);
      //獲取當前的用戶對象Subject
      Subject currentUser = SecurityUtils.getSubject();
      //通過當前用戶拿到session
      Session session = currentUser.getSession();
      session.setAttribute("someKey", "aValue");
      String value = (String) session.getAttribute("someKey");
      if (value.equals("aValue")) {
          log.info("Subject=>session[" + value + "]");
      }
      //判斷當前的用戶是否被認證
      if (!currentUser.isAuthenticated()) {
          //Token :令牌,沒有獲取,隨機
          UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
          token.setRememberMe(true);  //設置記住我
          try {
              currentUser.login(token); //執行了登錄操作
          } catch (UnknownAccountException uae) {
              //如果   用戶名不存在
              log.info("There is no user with username of " + token.getPrincipal());
          } catch (IncorrectCredentialsException ice) {
              //如果   密碼不正確
              log.info("Password for account " + token.getPrincipal() + " was incorrect!");
          } catch (LockedAccountException lae) {
              //用戶被鎖定,如密碼輸出過多,則被鎖定
              log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                      "Please contact your administrator to unlock it.");
          }
          //...在此處捕獲更多異常
          catch (AuthenticationException ae) {
              //意外情況 ? 錯誤 ?
          }
      }
      //打印其標識主體(在這種情況下,為用戶名)
      log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

      //測試角色是否存在
      if (currentUser.hasRole("schwartz")) {
          log.info("May the Schwartz be with you!");
      } else {
          log.info("Hello, mere mortal.");
      }
      //粗粒度,極限范圍小
      //測試類型化的極限(不是實例級別)
      if (currentUser.isPermitted("lightsaber:wield")) {
          log.info("You may use a lightsaber ring.  Use it wisely.");
      } else {
          log.info("Sorry, lightsaber rings are for schwartz masters only.");
      }
      //細粒度,極限范圍廣
      //實例級別的權限(非常強大)
      if (currentUser.isPermitted("winnebago:drive:eagle5")) {
          log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                  "Here are the keys - have fun!");
      } else {
          log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
      }
      //注銷
      currentUser.logout();
      //退出
      System.exit(0);
  }
}

 

三、SpringBoot 集成 Shiro

1.編寫測試環境

1.在剛剛的父項目中新建一個 springboot 模塊

Java Apache Shiro安全框架快速開發詳解流程

2.導入 SpringBoot 和 Shiro 整合包的依賴

<!--SpringBoot 和 Shiro 整合包-->
      <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-spring</artifactId>
          <version>1.4.1</version>
      </dependency>

下面是編寫配置文件
Shiro 三大要素

Subject 用戶 -> ShiroFilterFactoryBean
SecurityManager 管理所有用戶 -> DefaultWebSecurityManager
Realm 連接數據

實際操作中對象創建的順序 : realm -> securityManager -> subject

3.編寫自定義的 realm ,需要繼承 AuthorizingRealm

//自定義的 UserRealm        extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
  //授權
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
      //打印一個提示
      System.out.println("執行了授權方法");
      return null;
  }

  //認證
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
      //打印一個提示
      System.out.println("執行了認證方法");
      return null;
  }
}

4.新建一個ShiroConfig配置文件

@Configuration
public class ShiroConfig {

  //ShiroFilterFactoryBean:3
  @Bean
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
      ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
      //設置安全管理器
      bean.setSecurityManager(defaultWebsecurityManager);
      return bean;
  }
  //DefaultWebSecurityManager:2
  @Bean(name="securityManager")
  public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
      DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
      //關閉UserRealm
      securityManager.setRealm(userRealm);
      return securityManager;
  }
  //創建realm 對象,需要自定義類:1
  @Bean(name="userRealm")
  public UserRealm userRealm(){
      return new UserRealm();
  }
}

5.測試成功!

Java Apache Shiro安全框架快速開發詳解流程

2.使用

1.登錄攔截

在getShiroFilterFactoryBean方法中添加需要攔截的登錄請求

@Configuration
public class ShiroConfig {

  //ShiroFilterFactoryBean:3
  @Bean
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
      ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
      //設置安全管理器
      bean.setSecurityManager(defaultWebsecurityManager);
      //添加shiro的內置過濾器
      /*
          anon : 無需認證,就可以訪問
          authc : 必須認證了才能訪問
          user : 必須擁有 “記住我” 功能才能用
          perms : 擁有對某個資源的權限才能訪問
          role : 擁有某個角色權限才能訪問
       */

      filterMap.put("/user/add","authc");
      filterMap.put("/user/update","authc");
      //攔截
      Map<String,String> filterMap=new LinkedHashMap<>();
      filterMap.put("/user/*","authc");
      bean.setFilterChainDefinitionMap(filterMap);

//        //設置登錄的請求
//        bean.setLoginUrl("/toLogin");
      return bean;
  }

測試:點擊 add鏈接,不會跳到 add 頁面,而是跳到登錄頁,攔截成功

Java Apache Shiro安全框架快速開發詳解流程

2.用戶認證

1.在Controller層寫一個登錄的方法

  //登錄的方法
  @RequestMapping("/login")
  public String login(String username, String password, Model model) {
      //獲取當前用戶
      Subject subject = SecurityUtils.getSubject();
      //封裝用戶的登錄數據,獲得令牌
      UsernamePasswordToken token = new UsernamePasswordToken(username, password);
      //登錄 及 異常處理
      try {
          //執行用戶登錄的方法,如果沒有異常就說明OK了
          subject.login(token);
          return "index";
      } catch (UnknownAccountException e) {
          //如果用戶名不存在
          System.out.println("用戶名不存在");
          model.addAttribute("msg", "用戶名錯誤");
          return "login";
      } catch (IncorrectCredentialsException ice) {
          //如果密碼錯誤
          System.out.println("密碼錯誤");
          model.addAttribute("msg", "密碼錯誤");
          return "login";
      }
  }
}

2.測試

Java Apache Shiro安全框架快速開發詳解流程

可以看出是先執行了自定義的UserRealm中的AuthenticationInfo方法,再執行登錄相關的操作

3.修改UserRealm中的doGetAuthenticationInfo方法

  //認證
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
      //打印一個提示
      System.out.println("執行了認證方法");
      // 用戶名密碼
      String name = "root";
      String password = "123456";
      //通過參數獲取登錄的控制器中生成的 令牌
      UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
      //用戶名認證
      if (!token.getUsername().equals(name)){
          // return null UnKnownAccountException
          return null;
      }
      //密碼認證, Shiro 自己做,為了避免和密碼的接觸
      //最后返回一個 AuthenticationInfo 接口的實現類,這里選擇 SimpleAuthenticationInfo
      // 三個參數:獲取當前用戶的認證 ; 密碼 ; 認證名
      return new SimpleAuthenticationInfo("", password, "");
  }
}

4.測試,輸入錯誤的密碼

Java Apache Shiro安全框架快速開發詳解流程

Java Apache Shiro安全框架快速開發詳解流程

輸入正確的密碼,即可登錄成功

 

四、Shiro整合Mybatis

1.導入依賴

      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.19</version>
      </dependency>

      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>

      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.12</version>
      </dependency>
     <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>2.1.1</version>
      </dependency>

2.新建個application.yml

spring:
datasource:
  username: root
  password: 123456
  url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
  driver-class-name: com.mysql.cj.jdbc.Driver
  type: com.alibaba.druid.pool.DruidDataSource

  #Spring Boot 默認是不注入這些屬性值的,需要自己綁定
  #druid 數據源專有配置
  initialSize: 5
  minIdle: 5
  maxActive: 20
  maxWait: 60000
  timeBetweenEvictionRunsMillis: 60000
  minEvictableIdleTimeMillis: 300000
  validationQuery: SELECT 1 FROM DUAL
  testWhileIdle: true
  testOnBorrow: false
  testOnReturn: false
  poolPreparedStatements: true

  #配置監控統計攔截的filters,stat:監控統計、log4j:日志記錄、wall:防御sql注入
  #如果允許時報錯  java.lang.ClassNotFoundException: org.apache.log4j.Priority
  #則導入 log4j 依賴即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
  filters: stat,wall,log4j
  maxPoolPreparedStatementPerConnectionSize: 20
  useGlobalDataSourceStat: true
  connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis:
type-aliases-package: com.huang.pojo
mapper-locations: classpath:mybatis/mapper/*.xml

3.在application.properties

mybatis.type-aliases-package=com.longdi.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

4.導入依賴

      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.10</version>
          <scope>provided</scope>
      </dependency>

5.編寫User類

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
      private int id;
      private String name;
      private String pwd;
      private String perms;
}

6.編寫UserMapper

@Repository
@Mapper
public interface UserMapper {
  public User  queryUserByName(String name);

}

7.編寫UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.longdi.mapper.UserMapper">

  <select id="queryUserByName" resultType="User" parameterType="String">
      select * from mybatis.user where name=#{name}
  </select>

</mapper>

8.Service層

UserService接口:

public interface UserService {
  public User queryUserByName(String name);
}

9.編寫接口實現類UserServiceImpl

@Service
public class UserServiceImpl implements UserService{

  @Autowired
  UserMapper userMapper;

  @Override
  public User queryUserByName(String name) {
      return userMapper.queryUserByName(name);
  }
}

10.在ShiroSpringbootApplicationTests測試

@SpringBootTest
class ShiroSpringbootApplicationTests {
  @Autowired
  UserServiceImpl userService;
  @Test
  void contextLoads() {
      System.out.println(userService.queryUserByName("longdi"));
  }
}

11.成功連接數據庫

 

五、實現請求授權

1.在ShiroConfig類中修改

Java Apache Shiro安全框架快速開發詳解流程

2.controller跳轉

Java Apache Shiro安全框架快速開發詳解流程

3.登錄攔截授權,測試成功

Java Apache Shiro安全框架快速開發詳解流程

Java Apache Shiro安全框架快速開發詳解流程

4.編寫授權doGetAuthorizationInfo方法

Java Apache Shiro安全框架快速開發詳解流程

5.請求授權測試成功

 

六、Shiro整合Thymeleaf

1.導入依賴

      <!--shiro和thymeleaf整合-->
      <dependency>
          <groupId>com.github.theborakompanioni</groupId>
          <artifactId>thymeleaf-extras-shiro</artifactId>
          <version>2.0.0</version>
      </dependency>

2.整合ShiroDialect

Java Apache Shiro安全框架快速開發詳解流程

3.index.html

Java Apache Shiro安全框架快速開發詳解流程

4.測試

Java Apache Shiro安全框架快速開發詳解流程

5.在認證里放session

Java Apache Shiro安全框架快速開發詳解流程

6.修改index.html

Java Apache Shiro安全框架快速開發詳解流程

到此這篇關于Java Apache Shiro安全框架快速開發詳解流程的文章就介紹到這了,更多相關Java Shiro框架內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_48838340/article/details/120680536

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男女亲热网站 | 一级一级一级一级毛片 | 日韩av片在线播放 | 欧美一区二区三区久久久久久桃花 | 午夜视频在线免费观看 | www.狠狠插.com | 国产91久久精品一区二区 | 成年人免费视频播放 | 久久99精品视频在线观看 | 日本黄色一级电影 | 免费久久久| 男人午夜小视频 | 黄色网在线播放 | 曰本三级日本三级日本三级 | 天天舔夜夜操 | 欧美成人一区二区三区电影 | 国产精品三级a三级三级午夜 | 日韩伦理电影免费观看 | 欧美一区二区精品夜夜嗨 | 欧美成人精品一区二区 | 黄色影视大全 | 羞羞视频免费网站含羞草 | 亚洲精品 在线播放 | 91精品国产刺激国语对白 | 中文字幕亚洲一区二区三区 | 日韩视频精品 | 亚洲乱搞 | 内地av在线 | 欧美 日韩 亚洲 中文 | 久久亚洲线观看视频 | 香蕉成人在线视频 | 日韩视频―中文字幕 | www.99av| a黄网站 | 一区二区三区日韩在线 | 日韩一级免费毛片 | 欧美一级精品 | 黄网站在线播放视频免费观看 | 99热久草 | 日韩精品免费看 | 日韩精品中文字幕一区二区三区 |