許可權框架之Shiro詳解

来源:https://www.cnblogs.com/WUXIAOCHANG/archive/2019/05/18/10886534.html
-Advertisement-
Play Games

文章大綱 一、許可權框架介紹二、Shiro基礎介紹三、Spring Boot整合Shiro代碼實戰四、項目源碼與資料下載五、參考文章 一、許可權框架介紹 1. 什麼是許可權管理 許可權管理屬於系統安全的範疇,許可權管理實現對用戶訪問系統的控制,按照安全規則或者安全策略控制用戶可以訪問而且只能訪問自己被授權的資 ...


文章大綱

一、許可權框架介紹
二、Shiro基礎介紹
三、Spring Boot整合Shiro代碼實戰
四、項目源碼與資料下載
五、參考文章

 

一、許可權框架介紹

1. 什麼是許可權管理

  許可權管理屬於系統安全的範疇,許可權管理實現對用戶訪問系統的控制,按照安全規則或者安全策略控制用戶可以訪問而且只能訪問自己被授權的資源。
  許可權管理包括用戶身份認證和授權兩部分,簡稱認證授權。對於需要訪問控制的資源用戶首先經過身份認證,認證通過後用戶具有該資源的訪問許可權方可訪問。
1.1 用戶身份認證
  身份認證,就是判斷一個用戶是否為合法用戶的處理過程。最常用的簡單身份認證方式是系統通過核對用戶輸入的用戶名和口令,看其是否與系統中存儲的該用戶的用戶名和口令一致,來判斷用戶身份是否正確。對於採用指紋等系統,則出示指紋;對於硬體Key等刷卡系統,則需要刷卡。

用戶名密碼身份認證流程:

 

1.2 授權流程
  授權,即訪問控制,控制誰能訪問哪些資源。主體進行身份認證後需要分配許可權方可訪問系統的資源,對於某些資源沒有許可權是無法訪問的。

 

2. 常見許可權框架

2.1 Shiro簡介
  Apache Shiro是Java的一個安全框架。目前,使用Apache Shiro的人越來越多,因為它相當簡單,對比Spring Security,可能沒有Spring Security做的功能強大,但是在實際工作時可能並不需要那麼複雜的東西,所以使用小而簡單的Shiro就足夠了。對於它倆到底哪個好,這個不必糾結,能更簡單的解決項目問題就好了。

2.2 Spring Security
  Spring Security是一個能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴註入)和AOP(面向切麵編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重覆代碼的工作。它是一個輕量級的安全框架,它確保基於Spring的應用程式提供身份驗證和授權支持。它與Spring MVC有很好地集成,並配備了流行的安全演算法實現捆綁在一起。安全主要包括兩個操作“認證”與“驗證”(有時候也會叫做許可權控制)。“認證”是為用戶建立一個其聲明的角色的過程,這個角色可以一個用戶、一個設備或者一個系統。“驗證”指的是一個用戶在你的應用中能夠執行某個操作。在到達授權判斷之前,角色已經在身份認證過程中建立了。

2.3 Shiro和Spring Security比較
(1)Shiro比Spring更容易使用,實現和最重要的理解
(2)Spring Security更加知名的唯一原因是因為品牌名稱
(3)“Spring”以簡單而聞名,但諷刺的是很多人發現安裝Spring Security很難
(4)Spring Security卻有更好的社區支持
(5)Apache Shiro在Spring Security處理密碼學方面有一個額外的模塊
(6)Spring-security 對spring 結合較好,如果項目用的springmvc ,使用起來很方便。但是如果項目中沒有用到spring,那就不要考慮它了。
(7)Shiro 功能強大、且 簡單、靈活。是Apache 下的項目比較可靠,且不跟任何的框架或者容器綁定,可以獨立運行

二、Shiro基礎介紹

1. Shiro三個核心組件

1.1 Subject
  Subject:即“當前操作用發戶”。但是,在Shiro中,Subject這一概念並不僅僅指人,也可以是第三方進程、後臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當前跟軟體交互的東西”。但考慮到大多數目的和用途,你可以把它認為是Shiro的“用戶”概念。Subject代表了當前用戶的安全操作,SecurityManager則管理所有用戶的安全操作。

1.2 SecurityManager
  SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,並通過它來提供安全管理的各種服務。

1.3 Realm
  Realm充當了Shiro與應用安全數據間的“橋梁”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其許可權信息。
  從這個意義上講,Realm實質上是一個安全相關的DAO:它封裝了數據源的連接細節,併在需要時將相關數據提供給Shiro。當配置Shiro時,你必須至少指定一個Realm,用於認證和(或)授權。配置多個Realm是可以的,但是至少需要一個。
  Shiro內置了可以連接大量安全數據源(又名目錄)的Realm,如LDAP、關係資料庫(JDBC)、類似INI的文本配置資源以及屬性文件等。如果預設的Realm不能滿足需求,你還可以插入代表自定義數據源的自己的Realm實現。

2. Shiro相關類介紹

(1)Authentication 認證 ---- 用戶登錄
(2)Authorization 授權 --- 用戶具有哪些許可權
(3)Cryptography 安全數據加密
(4)Session Management 會話管理
(5)Web Integration web系統集成
(6)Interations 集成其它應用,spring、緩存框架

3. Shiro 特點

(1)易於理解的 Java Security API;
(2)簡單的身份認證(登錄),支持多種數據源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
(3)對角色的簡單的簽權(訪問控制),支持細粒度的簽權;
(4)支持一級緩存,以提升應用程式的性能;
(5)內置的基於 POJO 企業會話管理,適用於 Web 以及非 Web 的環境;
(6)異構客戶端會話訪問;
(7)非常簡單的加密 API;
(8)不跟任何的框架或者容器捆綁,可以獨立運行

三、Spring Boot整合Shiro代碼實戰

1. Spring Boot基礎

https://www.cnblogs.com/WUXIAOCHANG/p/10877266.html

2. 創建Spring Boot的基礎項目

2.1 新建maven項目

     

創建後項目結構如下:

 

2.2 pom.xml中添加依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 繼承Spring Boot的預設父工程 -->
    <!-- Spring Boot 父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>

    <groupId>com.itheima</groupId>
    <artifactId>springboot-shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <!-- 導入依賴 -->
    <dependencies>

        <!-- 導入web支持:SpringMVC開發支持,Servlet相關的程式 -->
        <!-- web支持,SpringMVC, Servlet支持等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>


    <!-- 修改參數 -->
    <properties>
        <!-- 修改JDK的編譯版本為1.8 -->
        <java.version>1.8</java.version>
    </properties>
</project>

2.3 編寫測試Controller類
com.itheima.controller包下新建UserController.java

package com.itheima.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    /**
     * 測試方法
     */
    @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        System.out.println("UserController.hello()");
        return "ok";
    }
}

2.4 導入thymeleaf頁面模塊
pom.xml文件中添加依賴

<!-- 導入thymeleaf依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

UserController.java類中添加測試方法

    /**
     * 測試thymeleaf
     */
    @RequestMapping("/testThymeleaf")
    public String testThymeleaf(Model model){
        //把數據存入model
        model.addAttribute("name", "吳先生");
        //返回test.html
        return "test";
    }

2.5 添加thymeleaf頁面模塊
在src/main/resource目錄下創建templates目錄,然後創建test.html頁面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>測試Thymeleaf的使用</title>
</head>
<body>
<h3 th:text="${name}"></h3>
</body>
</html>
 

2.6 運行項目並訪問
運行項目

 

訪問項目

   

3. Spring Boot與Shiro整合實現用戶認證

3.1 分析Shiro的核心API
Subject: 用戶主體(把操作交給SecurityManager)
SecurityManager:安全管理器(關聯Realm)
Realm:Shiro連接數據的橋梁

3.2 導入shiro與spring整合依賴
pom.xml文件中添加依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 繼承Spring Boot的預設父工程 -->
    <!-- Spring Boot 父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>

    <groupId>com.itheima</groupId>
    <artifactId>springboot-shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <!-- 導入依賴 -->
    <dependencies>

        <!-- 導入web支持:SpringMVC開發支持,Servlet相關的程式 -->
        <!-- web支持,SpringMVC, Servlet支持等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 導入thymeleaf依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- shiro與spring整合依賴 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

        <!-- 導入mybatis相關的依賴 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- SpringBoot的Mybatis啟動器 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!-- thymel對shiro的擴展坐標 -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

    </dependencies>


    <!-- 修改參數 -->
    <properties>
        <!-- 修改JDK的編譯版本為1.8 -->
        <java.version>1.8</java.version>
        <!-- 修改thymeleaf的版本 -->
        <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
    </properties>

    <build>
        <!--解決項目運行後mapper.xmlw文件找不到情況-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>

3.3 resources下配置
新建application.properties文件

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro_test
spring.datasource.username=root
spring.datasource.password=147258qq

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

mybatis.type-aliases-package=com.itheima.domain

templates文件夾下加入相關模板頁面

add.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶添加頁面</title>
</head>
<body>
用戶添加
</body>
</html>

update.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用戶更新頁面</title>
</head>
<body>
用戶更新
</body>
</html>

login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
</head>
<body>
<h3>登錄</h3>
<h3 th:text="${msg}" style="color: red"></h3>

<form method="post" action="login">
    用戶名:<input type="text" name="name"/><br/>
    密碼:<input type="password" name="password"/><br/>
    <input type="submit" value="登錄"/>
</form>
</body>
</html>

noAuth.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>未授權提示頁面</title>
</head>
<body>
親,你未經授權訪問該頁面
</body>
</html>
 

3.4 新建shiro相關配置
com.itheima.shiro包下新建ShiroConfig.java類

package com.itheima.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

/**
 * Shiro的配置類
 * 
 * 關於Configuration的講解,可參考一下博客:https://www.cnblogs.com/WUXIAOCHANG/p/10877266.html
 * @author lenovo
 *
 */
@Configuration
public class ShiroConfig {

    /**
     * 創建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        
        //設置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        //添加Shiro內置過濾器
        /**
         * Shiro內置過濾器,可以實現許可權相關的攔截器
         *    常用的過濾器:
         *       anon: 無需認證(登錄)可以訪問
         *       authc: 必須認證才可以訪問
         *       user: 如果使用rememberMe的功能可以直接訪問
         *       perms: 該資源必須得到資源許可權才可以訪問
         *       role: 該資源必須得到角色許可權才可以訪問
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        /*filterMap.put("/add", "authc");
        filterMap.put("/update", "authc");*/
        
        filterMap.put("/testThymeleaf", "anon");
        //放行login.html頁面
        filterMap.put("/login", "anon");
        
        //授權過濾器
        //註意:當前授權攔截後,shiro會自動跳轉到未授權頁面
        //perms括弧中的內容是許可權的值
        filterMap.put("/add", "perms[user:add]");
        filterMap.put("/update", "perms[user:update]");
        
        filterMap.put("/*", "authc");
        
        //修改調整的登錄頁面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //設置未授權提示頁面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        
        
        return shiroFilterFactoryBean;
    }
    
    /**
     * 創建DefaultWebSecurityManager
     * 
     * 裡面主要定義了登錄,創建subject,登出等操作
     */
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //關聯realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    
    /**
     * 創建Realm
     */
    @Bean(name="userRealm")
    public UserRealm getRealm(){
        return new UserRealm();
    }
    
    /**
     * 配置ShiroDialect,用於thymeleaf和shiro標簽配合使用
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

com.itheima.shiro包下新建UserRealm.java類

package com.itheima.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.itheima.domain.User;
import com.itheima.service.UserService;

/**
 * 自定義Realm
 * (1)AuthenticatingRealm:shiro中的用於進行認證的領域,實現doGetAuthentcationInfo方法實現用戶登錄時的認證邏輯;
 * (2)AuthorizingRealm:shiro中用於授權的領域,實現doGetAuthrozitionInfo方法實現用戶的授權邏輯,AuthorizingRealm繼承了AuthenticatingRealm,
 * 所以在實際使用中主要用到的就是這個AuthenticatingRealm類;
 * (3)AuthenticatingRealm、AuthorizingRealm這兩個類都是shiro中提供了一些線程的realm介面
 * (4)在與spring整合項目中,shiro的SecurityManager會自動調用這兩個方法,從而實現認證和授權,可以結合shiro的CacheManager將認證和授權信息保存在緩存中,
 * 這樣可以提高系統的處理效率。    
 *
 */
public class UserRealm extends AuthorizingRealm{

    @Autowired
    private UserService userSerivce;

    /**
     * 執行認證邏輯
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        System.out.println("執行認證邏輯");

        //編寫shiro判斷邏輯,判斷用戶名和密碼
        //1.判斷用戶名  token中的用戶信息是登錄時候傳進來的
        UsernamePasswordToken token = (UsernamePasswordToken)arg0;

        User user = userSerivce.findByName(token.getUsername());

        if(user==null){
            //用戶名不存在
            return null;//shiro底層會拋出UnKnowAccountException
        }

        //2.判斷密碼
        //第二個欄位是user.getPassword(),註意這裡是指從資料庫中獲取的password。第三個欄位是realm,即當前realm的名稱。
        //這塊對比邏輯是先對比username,但是username肯定是相等的,所以真正對比的是password。
        //從這裡傳入的password(這裡是從資料庫獲取的)和token(filter中登錄時生成的)中的password做對比,如果相同就允許登錄,
        // 不相同就拋出IncorrectCredentialsException異常。
        //如果認證不通過,就不會執行下麵的授權方法了
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

    /**
     * 執行授權邏輯
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

        //doGetAuthorizationInfo方法可能會執行多次,許可權判斷次數多少,就會執行多少次
        System.out.println("執行授權邏輯1");
        System.out.println("執行授權邏輯2");
        
        //給資源進行授權
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        //添加資源的授權字元串
        //info.addStringPermission("user:add");
        
        //到資料庫查詢當前登錄用戶的授權字元串
        //獲取當前登錄用戶
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        User dbUser = userSerivce.findById(user.getId());
        
        info.addStringPermission(dbUser.getPerms());
        
        return info;
    }
}

3.5 新建實體類
com.itheima.domain包下新建User.java

package com.itheima.domain;

public class User {
    private Integer id;
    private String name;
    private String password;
    private String perms;
    public String getPerms() {
        return perms;
    }
    public void setPerms(String perms) {
        this.perms = perms;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}

3.6 創建mapper相關內容
com.itheima.mapper包下新建UserMapper.java

package com.itheima.mapper;

import com.itheima.domain.User;

public interface UserMapper {

    public User findByName(String name);
    
    public User findById(Integer id);
}

com.itheima.mapper包下新建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">
<!-- 該文件存放CRUD的sql語句 -->
<mapper namespace="com.itheima.mapper.UserMapper">
    
    <select id="findByName" parameterType="string" resultType="user">
    SELECT  id, 
        NAME, 
        PASSWORD
        FROM 
        user where name = #{value}
    </select>
    
    <select id="findById" parameterType="int" resultType="user">
        SELECT  id, 
        NAME, 
        PASSWORD,
        perms 
        FROM 
        user where id = #{value}
    </select>
</mapper>

3.7 創建業務邏輯相關內容
com.itheima.service下新建UserService.java

package com.itheima.service;

import com.itheima.domain.User;

public interface UserService {

    public User findByName(String name);
    
    public User findById(Integer id);
}

com.itheima.service.impl下新建UserServiceImpl.java

package com.itheima.service.impl;

import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.itheima.domain.User;
import com.itheima.mapper.UserMapper;
import com.itheima.service.UserService;

@Service
public class UserServiceImpl implements UserService{

    //註入Mapper介面
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public User findByName(String name) {
        return userMapper.findByName(name);
    }

    @Override
    public User findById(Integer id) {
        return userMapper.findById(id);
    }

}

3.8 新建Controller相關內容
UserController.java添加相關代碼,最終內容如下:

package com.itheima.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.itheima.service.UserService;

@Controller
public class UserController {

    /**
     * 測試方法
     */
    @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        System.out.println("UserController.hello()");
        return "ok";
    }
    
    @RequestMapping("/add")
    public String add(){
        return "/user/add";
    }
    
    @RequestMapping("/update")
    public String update(){
        return "/user/update";
    }
    
    @RequestMapping("/toLogin")
    public String toLogin(){
        return "/login";
    }
    
    @RequestMapping("/noAuth")
    public String noAuth(){
        return "/noAuth";
    }

    /**
     * 測試thymeleaf
     */
    @RequestMapping("/testThymeleaf")
    public String testThymeleaf(Model model){
        //把數據存入model
        model.addAttribute("name", "吳先生");
        //返回test.html
        return "test";
    }
    
    /**
     * 登錄邏輯處理
     */
    @RequestMapping("/login")
    public String login(String name,String password,Model model){
        System.out.println("name="+name);
        /**
         * 使用Shiro編寫認證操作
         */
        //1.獲取Subject
        Subject subject = SecurityUtils.getSubject();
        
        //2.封裝用戶數據
        UsernamePasswordToken token = new UsernamePasswordToken(name,password);
        
        //3.執行登錄方法
        try {
            subject.login(token);
            
            //登錄成功
            //跳轉到test.html
            return "redirect:/testThymeleaf";
        } catch (UnknownAccountException e) {
            //e.printStackTrace();
            //登錄失敗:用戶名不存在,UnknownAccountException是Shiro拋出的找不到用戶異常
            model.addAttribute("msg", "用戶名不存在");
            return "login";
        }catch (IncorrectCredentialsException e) {
            //e.printStackTrace();


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們在項目開發中有很多地方使用到了註解,關於註解的定義與創建小伙伴可以參考我的文章《java註解》。有任何問題的小伙伴們可以在評論區指出哦,歡迎各位大佬指出問題。 今天我要說的是使用註解與反射結合使用,來使我們代碼根據優雅,更加高大上(咳,裝逼神器啊)。 註解使用@interface 來定義,辣麽我 ...
  • [轉載] Python數據類型知識點全解 1.字元串 字元串常用功能 字元串的內置方法 2.列表 3.元組 4.字典 5.集合 ...
  • 1041. 困於環中的機器人 題庫鏈接: 1041. 困於環中的機器人. 題乾 在無限的平面上,機器人最初位於 (0, 0) 處,面朝北方。機器人可以接受下列三條指令之一: "G":直走 1 個單位 "L":左轉 90 度 "R":右轉 90 度 機器人按順序執行指令 instructions,並一 ...
  • //原文參考https://blog.csdn.net/lanchunhui/article/details/52503332 你以為你定義了一個類的對象,其實在編譯器看來你是聲明瞭一個函數 修改為: 當構造函數中存在一些參數時: 當構造函數的參數帶預設值: ...
  • [toc] 創建ashop sso web單點登陸系統 先創建好模塊, 然後配置pom.xml文件 加入spring的配置文件 然後配置web.xml文件, 並把靜態資源放到webapp目錄下. 打包部署模塊測試, 能看到如下效果則項目搭建成功.   用戶名唯一性驗證 |請求方法|GET| ...
  • day23 03 組合的例子 一、用到組合的方式,編寫一個圓環,並能夠計算出它的周長和麵積 運行結果: 二、創建一個老師類,老師有生日,生日也是一個類,涉及組合的方法 運行結果: 三、複習 1、面向對象編程 思想:角色的抽象,創建類,創建角色(實例化),操作這些實例 關鍵字:class 基本框架: ...
  • 本人是一位學生,正在學習當中,可能BUG眾多,請見諒並指正,謝謝!!! 學生列表實現 HTML: PHP: 添加學生實現 HTML: PHP: ...
  • 在eclipse裡面運行代碼即可,如果您是其他應用,請選擇對您有幫助的代碼即可,如果有寫錯或不懂的地方請聯繫QQ:1633420056,謝謝,祝學習進步 <!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...