springboot框架簡介
Spring的誕生是 Java 企業版(Java Enterprise Edition,JEE,也稱 J2EE)的
輕量級代替品。無需開發重量級的 Enterprise JavaBean(EJB),Spring 爲企業級
Java 開發提供了一種相對簡單的方法,通過依賴注入和麪向切面編程,用簡單的Java 對象(Plain Old Java Object,POJO)實現了 EJB 的功能
Spring Boot 簡化了基於Spring的應用開發,只需要“run”就能創建一個獨立的、生產級別的Spring應用。Spring Boot爲Spring平臺及第三方庫提供開箱即用的設置(提供默認設置),這樣我們就可以簡單的開始。多數Spring Boot應用只需要很少的Spring配置。
Spring Boot 主要目標是:
- 爲所有 Spring 的開發提供一個從根本上更快的入門體驗。
- 開箱即用,但通過自己設置參數,即可快速擺脫這種方式。
- 提供了一些大型項目中常見的非功能性特性,如內嵌服務器、安全、指標,健康檢測、外部化配置等。
- 絕對沒有代碼生成,也無需 XML 配置。
Shiro框架簡介
Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。
Apache Shiro 體系結構
- Authentication 認證 ---- 用戶登錄
- Authorization 授權 --- 用戶具有哪些權限
- Cryptography 安全數據加密
- Session Management 會話管理
- Web Integration web系統集成
- Interations 集成其它應用,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>
</project>
springboot啓動類:
package com.itheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SpringBoot啓動類
* @author lenovo
*
*/
@SpringBootApplication
@MapperScan("com.itheima.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
shiro核心API
Subject: 用戶主體(把操作交給SecurityManager)
SecurityManager:安全管理器(關聯Realm)
Realm:Shiro連接數據的橋樑
shiors配置文件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的配置類
* @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會自動跳轉到未授權頁面
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
*/
@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();
}
}
自定義Realm,代碼如下:
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
* @author lenovo
*
*/
public class UserRealm extends AuthorizingRealm{
/**
* 執行授權邏輯
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("執行授權邏輯");
//給資源進行授權
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;
}
@Autowired
private UserService userSerivce;
/**
* 執行認證邏輯
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
System.out.println("執行認證邏輯");
//編寫shiro判斷邏輯,判斷用戶名和密碼
//1.判斷用戶名
UsernamePasswordToken token = (UsernamePasswordToken)arg0;
User user = userSerivce.findByName(token.getUsername());
if(user==null){
//用戶名不存在
return null;//shiro底層會拋出UnKnowAccountException
}
//2.判斷密碼
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}