1. 程式人生 > >Spring Boot 整合 Shiro 進行登入認證

Spring Boot 整合 Shiro 進行登入認證

安全無處不在,趁著放假讀了一下 Shiro 文件,並記錄一下 Shiro 整合 Spring Boot 在資料庫中根據角色控制訪問許可權

簡介

Apache Shiro是一個功能強大、靈活的,開源的安全框架。它可以乾淨利落地處理身份驗證、授權、企業會話管理和加密。
Shiro Architecture

上圖是 Shiro 的基本架構

Authentication(認證)

有時被稱為“登入”,用來證明使用者是使用者他們自己本人

訪問控制的過程,即確定“誰”訪問“什麼”

Session Management(會話管理)

管理使用者特定的會話,在 Shiro 裡面可以發現所有的使用者的會話資訊都會由 Shiro 來進行控制

Cryptography(加密)

在對資料來源使用加密演算法加密的同時,保證易於使用

Start

環境

Spring Boot 1.5.9
MySQL 5.7
Maven 3.5.2
Spring Data Jpa
Lombok

新增依賴

這裡只給出主要的 Shiro 依賴

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId
>
<version>1.4.0-RC2</version> </dependency>

配置

我們暫時只需要使用者表、角色表,在 Spring boot 中修改配置檔案將自動為我們建立資料庫表

server:
  port: 8888
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/shiro?characterEncoding=utf-8&useSSL=false
jpa: generate-ddl: true hibernate: ddl-auto: update show-sql: true

實體

Role.java

@Data
@Entity
public class Role {

    @Id
    @GeneratedValue
    private Integer id;

    private Long userId;

    private String role;

}

User.java

@Data
@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;

    private String username;

    private String password;

}

Realm

首先建立 Realm 類,繼承自 AuthorizingRealm,自定義我們自己的授權和認證的方法。Realm 是可以訪問特定於應用程式的安全性資料(如使用者,角色和許可權)的元件。

Realm.java

public class Realm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //從憑證中獲得使用者名稱
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        //根據使用者名稱查詢使用者物件
        User user = userService.getUserByUserName(username);
        //查詢使用者擁有的角色
        List<Role> list = roleService.findByUserId(user.getId());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (Role role : list) {
            //賦予使用者角色
            info.addStringPermission(role.getRole());
        }
        return info;
    }

    //認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //獲得當前使用者的使用者名稱
        String username = (String) authenticationToken.getPrincipal();

        //從資料庫中根據使用者名稱查詢使用者
        User user = userService.getUserByUserName(username);
        if (userService.getUserByUserName(username) == null) {
            throw new UnknownAccountException(
                    "沒有在本系統中找到對應的使用者資訊。");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(),getName());
        return info;
    }

}

Shiro 配置類

ShiroConfig.java

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //以下是過濾鏈,按順序過濾,所以/**需要放最後
        //開放的靜態資源
        filterChainDefinitionMap.put("/favicon.ico", "anon");//網站圖示
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(myRealm());
        return defaultWebSecurityManager;
    }

    @Bean
    public MyRealm myRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }
}

控制器

UserController.java

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @GetMapping("/login")
    public String toLogin() {
        return "login";
    }

    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }

    @PostMapping("/login")
    public String doLogin(String username, String password) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:admin";
    }

    @GetMapping("/home")
    public String home() {
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.checkPermission("admin");
        } catch (UnauthorizedException exception) {
            System.out.println("沒有足夠的許可權");
        }
        return "home";
    }

    @GetMapping("/logout")
    public String logout() {
        return "index";
    }
}

Service

UserService.java

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public User getUserByUserName(String username) {
        return userDao.findByUsername(username);
    }

    @RequiresRoles("admin")
    public void send() {
        System.out.println("我現在擁有角色admin,可以執行本條語句");
    }

}

展示層

admin.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en"/>
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>

<form action="/login" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="登入" />
</form>

</body>
</html>

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en"/>
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
home
</body>
</html>

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en"/>
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
index
<a href="/login">請登入</a>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en"/>
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>

<form action="/login" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="登入" />
</form>

</body>
</html>

總結

這個小案例實現了根據角色來控制使用者訪問,其中最重要的就是 Realm,它充當了Shiro與應用安全資料間的“橋樑”或者“聯結器”

相關推薦

Spring Boot 整合 Shiro 進行登入認證

安全無處不在,趁著放假讀了一下 Shiro 文件,並記錄一下 Shiro 整合 Spring Boot 在資料庫中根據角色控制訪問許可權 簡介 Apache Shiro是一個功能強大、靈活的,開源的安全框架。它可以乾淨利落地處理身份驗證、授權、企業會話管理和

Spring Boot 整合Shiro實現登陸認證和許可權控制

我在做畢設的時候,使用了Shiro作為專案中的登陸認證和許可權控制。 下面是我專案中如何實現整合shiro的學習記錄。 匯入shiro依賴包到pom.xml <!-- Shiro依賴 --> <dependency>

spring boot整合Shiro實現單點登入

前面的部落格中,我們說道了Shiro的兩個最大的特點,認證和授權,而單點登入也是屬於認證的一部分,預設情況下,Shiro已經為我們實現了和Cas的整合,我們加入整合的一些配置就ok了。 1、加入shiro-cas包 <!-- shiro整合cas單點 -->

spring整合shiro實現登入認證自定義驗證功能(認證採用國密SM4演算法)

        公司在建專案採用的開發框架為spring+springMvc+hibernate,安全框架採用的是shiro,安全認證沿用了shiro自帶的HashedCredentialsMatcher,現客戶(國企)要求使用者密碼必須採用國密SM4演算法進行加密,因此需

Spring Boot 整合 Shiro實現認證及授權管理

Spring Boot Shiro 本示例要內容 基於RBAC,授權、認證 加密、解密 統一異常處理 redis session支援 介紹 Apache Shiro 是一個功能強大且易於使用的Java安全框架,可執行身份驗證,授權,加密和會話管理。藉助Shiro易於理解的API,您可以快速輕鬆地保護任何應

spring boot整合shiro 簡單許可權控制

package me.config; import javax.annotation.Resource; import me.domain.entity.CmsUser; import me.service.UserService; import me.utils.MD5Util

Spring Boot 整合 Shiro實現許可權控制,親測可用,附帶sql

前提: 本文主要講解Spring Boot 與 Shiro的整合 與許可權控制的實現方式(主要以程式碼實現功能為主),主要用到的技術Spring Boot+Shiro+Jpa(通過Maven構建),並不會涉及到Shiro框架的原始碼分析 如果有想要學習Shiro框架的小夥伴可以去http://shiro.

spring-boot整合shiro

概述 許可權體系在現代任何IT系統中都是很基礎但又非常重要的部分,無論是傳統MIS系統還是網際網路系統,出於保護業務資料和應用自身的安全,都會設計自己的授權鑑權策略。 最近專案中也需要用到許可權驗證功能,專案為spring-boot工程,現成的許可權驗證框架有shiro和spri

Spring Boot整合shiro

shiro面世已經有很長時間了,相比Spring security更加精簡一些,也更容易上手,因此就想分享下這段時間的學習成果,就當是學習筆記了1 pom檔案如下<project xmlns="http://maven.apache.org/POM/4.0.0" xml

spring boot 整合shiro(使用者授權和許可權控制)

(1) pom.xml中新增Shiro依賴 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId>

Spring Boot整合shiro,出現UnavailableSecurityManagerException 異常

問題描述:由於在java過濾器中通過User token = (User) SecurityUtils.getSubject().getPrincipal();獲取當前的登入使用者的資訊,報UnavailableSecurityManagerException這個異常。spr

spring boot 整合shiro 配置類報錯問題

這裡傳入的是下邊返回的自定義Realm,下邊是報錯,報的是該類不能被裝載,由jdk自己裝載,這裡不是太懂,記錄一下,由於錯誤太長,不好截圖,直接複製錯誤內容 >>>>>>>>>>>>>>&

Spring Boot 整合Shiro給Swagger&Druid放行資源

shiro的過濾器鏈配置: //放行靜態資源 filterChainDefinitionMap.put("/static/**", "anon");

spring boot整合shiroshiro過濾器介紹

過濾器鏈條配置說明 1、一個URL可以配置多個Filter,使用逗號分隔 2、當設定多個過濾器時,全部驗證通過,才視為通過 3、部分過濾器可指定引數,如perms,roles Shiro內建的FilterChain anon(org.apac

spring boot 整合shiro詳細教程

我們開發時候有時候要把傳統spring shiro轉成spring boot專案,或者直接整合,那麼我們要搞清楚一個知識,就是 xml配置和spring bean程式碼配置的關係,這一點很重要,因為spring boot是沒有xml配置檔案的(也不絕對,spring boot

Spring Boot 整合Shiro攔截Ajax請求

上一篇文章:Spring Boot 整合Shiro實現登陸認證和許可權控制,我們對shiro進行了整合。這一次我們具體來講一下shiro中的攔截器。 Shiro在處理非法請求比如沒有通過登入認證的請求

spring boot 整合shiro,swagger 加入攔截器後 swagger 不能訪問

在shiro的配置檔案中放行swagger: filterMap.put("/swagger-ui.html", "anon"); filterMap.put("/

spring boot 整合shiro的配置

spring boot提供了一個自帶的認證框架,同時也提供自定義的javaconfig配置擴充套件,spring-sercurity同樣也是優秀的框架,但是習慣了用apache shiro框架,而且原專案就是整合的shiro框架,到網上找了一下配置方式,沒找到完

spring boot 整合 shiro

版本說明: spring boot : 1.5.8.RELEASE shiro: 1.4.0 在沒有shiro-spring-boot-web-stater之前,我們通常的做法是把xx-shiro.xml中bean在configuration中定義,或者就是xml中進行定義

Spring Boot 整合Shiro和CAS

請大家在看本文之前,先了解如下知識點: 1、Shiro 是什麼?怎麼用? 2、Cas 是什麼?怎麼用? 3、最好有Spring基礎 首先看一下下面這張圖: 第一個流程是單純使用Shiro的流程。 第二個流程是單純使用Cas的流程。 第三個圖是Shiro整合Cas後的流程。 PS:流程圖急急