javascript
SpringBoot整合Shiro实现登录认证和授权CHCache
文章目錄
- 一、 springboot實現普通登錄
- 1 添加依賴
- 2 編寫配置文件
- 3 新建實體類和mapper
- 4 編寫業務層代碼
- 5 編寫控制器
- 6 編寫啟動類
- 7 編寫登錄頁面和主頁面
- 二、 springboot整合shiro實現登錄認證和憑證匹配
- 1 添加依賴
- 2 自定義Realm
- 3 編寫配置
- 4 userService新增單元方法:使用shiro認證
- 5 憑證匹配器
- 5.1 修改ShiroConfig
- 5.2 修改MyRealm
- 三、 remember me實現---shiro已經集成
- 1 修改application.yml-----增加shiro的loginUrl地址
- 2 增加記住我的按鈕
- 3 修改Controller
- 4 修改ShiroConfig
- 四、 配置退出
- 1 修改配置類
- 2 修改主頁面
- 五、 授權
- 1 簡介
- 2 Thymeleaf整合shiro
- 2.1 添加依賴
- 2.2 修改配置類(負責解析thymeleaf中shiro的相關屬性)
- 2.3 修改Realm
- 2.4 修改main.html
- 3 使用注解判斷方法是否具有權限執行
- 3.1 修改main.html
- 3.2 修改UserController類
- 3.3 新建依賴處理類
- 六 EHCache
- 1 ehcache簡介
- 2 EHCache API演示
- 2.1 添加依賴
- 2.2 新建配置文件
- 七 Shiro和EhCache整合
- 1 添加依賴
- 2 編寫ehcache緩存配置
- 3 修改配置文件
- 八 Shiro中Session對象獲取
一、 springboot實現普通登錄
1 添加依賴
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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><groupId>com.bjsxt</groupId><artifactId>02_shiro_springboot_login</artifactId><version>1.0-SNAPSHOT</version><!--配置繼承--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.10.RELEASE</version></parent><!--配置依賴--><dependencies><!--配置web啟動器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--配置mybatis啟動器--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.1</version></dependency><!--配置mysql驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency><!--配置Thrmeleaf啟動器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></project>2 編寫配置文件
新建application.yml
spring:datasource:driver-class-name: com.mysql.jdbc.Driverusername: rooturl: jdbc:mysql://localhost:3306/springboot-loginpassword: 1234 ##配置mapper的xml文件的路徑 mybatis:mapper-locations: classpath:mybatis/*.xml3 新建實體類和mapper
新建com.bjsxt.pojo.User
public class User {private Long id;private String username;private String pwd;// 省略getter和setter // 省略構造方法 }新建com.bjsxt.mapper.UserMapper
package com.bjsxt.mapper;public interface UserMapper {//根據用戶名查詢用戶信息@Select("select * from t_user where uname=#{uname}")User selUserInfoMapper(@Param("uname") String uname); }4 編寫業務層代碼
新建com.bjsxt.service.UserService及實現類
public interface UserService {//用戶登錄User selUserInfoService(String uname); } @Service public class UserServiceImpl implements UserService {//聲明mapper屬性@Autowiredprivate UserMapper userMapper;//用戶登錄@Overridepublic User selUserInfoService(String uname) {return userMapper.selUserInfoMapper(uname);} }5 編寫控制器
新建com.bjsxt.controller.UserController
package com.bjsxt.controller;@Controller public class UserController {//聲明service屬性@Autowiredprivate UserService userService;//聲明單元方法:登錄認證@RequestMapping("userLogin")public String userLogin(String uname,String pwd){//1.根據用戶名獲取用戶信息User user=userService.selUserInfoService(uname);//2.判斷用戶名是否合法if(user!=null){//3.校驗密碼if(user.getPwd().equals(pwd)){//認證成功return "main";}}return "error";}//聲明公共單元方法完成頁面的內部轉發@RequestMapping("{uri}")public String getPage(@PathVariable String uri){return uri;}}6 編寫啟動類
新建com.bjsxt.ShiroApplication
package com.bjsxt;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @MapperScan("com.bjsxt.mapper") public class ShiroApplication {public static void main(String[] args) {SpringApplication.run(ShiroApplication.class,args);}}7 編寫登錄頁面和主頁面
新建templates/login.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h3>SpringBoot整合Shiro登錄案例</h3><hr><!--創建登錄頁面--><form action="userLogin" method="post">用戶名: <input type="text" name="uname" value=""><br>密碼: <input type="password" name="pwd" value=""><br><input type="submit" value="登錄"></form></body> </html>新建templates/main.html。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head><meta charset="UTF-8"><title>Title</title> </head> <body>我是主頁面 </body> </html>二、 springboot整合shiro實現登錄認證和憑證匹配
1 添加依賴
<dependencies><!-- 注釋掉web啟動器是因為shiro-spring-boot-web-starter依賴了spring-boot-starter-web --><!-- <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>--><!--配置shiro的啟動器--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.4.2</version></dependency></dependencies>2 自定義Realm
新建com.bjsxt.shiro.MyRealm編寫認證邏輯
package com.bjsxt.shiro;//配置為Bean對象 @Component public class MyRealm extends AuthorizingRealm {//聲明業務層屬性@Autowiredprivate UserService userService;//自定義授權策略@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}//自定義認證策略@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//聲明認證代碼//1.獲取用戶傳遞的用戶名信息Object principal = token.getPrincipal();//2.根據用戶名獲取數據庫中的用戶信息User user = userService.selUserInfoService((String) principal);//3.認證if(user!=null){//用戶名是正確的//4.認證密碼AuthenticationInfo info= new SimpleAuthenticationInfo(principal,user.getPwd(), user.getUname());return info;}return null;} }3 編寫配置
新建com.bjsxt.config.ShiroConfig,編寫配置
package com.bjsxt.config;@Configuration public class ShiroConfig {//聲明MyRealm屬性@Autowiredprivate MyRealm myRealm;//聲明bean方法@Beanpublic DefaultWebSecurityManager securityManager(){DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();defaultWebSecurityManager.setRealm(myRealm);return defaultWebSecurityManager;}4 userService新增單元方法:使用shiro認證
package com.bjsxt.controller;@Controller public class UserController {//聲明單元方法:使用shiro認證@RequestMapping("userLogin2")public String userLogin2(String uname,String pwd){//1.獲取subject對象Subject subject = SecurityUtils.getSubject();//2.認證//創建認證對象存儲認證信息AuthenticationToken token= new UsernamePasswordToken(uname,pwd);try{subject.login(token);return "redirect:main";}catch(Exception e){e.printStackTrace();}return "redirect:login";}//聲明公共單元方法完成頁面的內部轉發@RequestMapping("{uri}")public String getPage(@PathVariable String uri){return uri;}}此時登錄出現問題:訪問login時報錯,錯誤說找不到login.jsp,應該找的是login.html
解決:在ShiroConfig配置類自定義shiro過濾器參數bean
將<form action="userLogin" method="post">改為<form action="userLogin2" method="post">
<body><h3>SpringBoot整合Shiro登錄案例</h3><hr><!--創建登錄頁面--><form action="userLogin2" method="post">用戶名: <input type="text" name="uname" value=""><br>密碼: <input type="password" name="pwd" value=""><br><input type="submit" value="登錄"></form> </body>啟動測試
5 憑證匹配器
首先將數據庫中用戶張三的密碼改為:6bdae6366c1e46d541eb0ca9547d974c
5.1 修改ShiroConfig
@Bean public DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager defaultWebSecurityManager= new DefaultWebSecurityManager();//創建憑證匹配器HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("md5");matcher.setHashIterations(2);myRealm.setCredentialsMatcher(matcher);//將自定義的認證策略對象注入到SecurityManagerdefaultWebSecurityManager.setRealm(myRealm);return defaultWebSecurityManager; }5.2 修改MyRealm
修改MyRealm中doGetAuthenticationInfo方法。
//自定義認證策略@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//聲明認證代碼//1.獲取用戶傳遞的用戶名信息Object principal = token.getPrincipal();//2.根據用戶名獲取數據庫中的用戶信息User user = userService.selUserInfoService((String) principal);//3.認證if(user!=null){//用戶名是正確的//4.認證密碼AuthenticationInfo info= new SimpleAuthenticationInfo(principal,user.getPwd(), ByteSource.Util.bytes(user.getUid()+""),user.getUname());return info;}return null;}三、 remember me實現—shiro已經集成
1 修改application.yml-----增加shiro的loginUrl地址
spring:datasource:driver-class-name: com.mysql.jdbc.Driverusername: rooturl: jdbc:mysql://localhost:3306/springboot-loginpassword: 1234 ##配置mapper的xml文件的路徑 mybatis:mapper-locations: classpath:mybatis/*.xml shiro:##當用戶訪問某個需要登錄的功能時,但是被shiro內置的過濾器攔截后,判斷本次請求##沒有登錄,而是直接訪問的,則重定向到loginUrl的路徑資源響應給用戶loginUrl: /login2 增加記住我的按鈕
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h3>SpringBoot整合Shiro登錄案例</h3><hr><!--創建登錄頁面--><form action="userLogin2" method="post">用戶名: <input type="text" name="uname" value=""><br>密碼: <input type="password" name="pwd" value=""><br><input type="submit" value="登錄"> <input type="checkbox" name="rememberme" value="true">記住俺</form></body> </html>3 修改Controller
@RequestMapping("userLogin2")public String userLogin2(String uname,String pwd,@RequestParam(defaultValue = "false") Boolean rememberme){//1.獲取subject對象Subject subject = SecurityUtils.getSubject();//2.認證//創建認證對象存儲認證信息AuthenticationToken token= new UsernamePasswordToken(uname,pwd,rememberme);try{subject.login(token);return "redirect:main";}catch(Exception e){e.printStackTrace();}return "redirect:login";}4 修改ShiroConfig
@Beanpublic DefaultWebSecurityManager securityManager(){DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();//創建憑證匹配器HashedCredentialsMatcher matcher=new HashedCredentialsMatcher();//設置匹配器的加密算法matcher.setHashAlgorithmName("md5");//設置匹配器的迭代加密次數matcher.setHashIterations(2);//將匹配器注入到自定義的認證策略對象中myRealm.setCredentialsMatcher(matcher);//將自定義的認證策略對象注入到SecurityManagerdefaultWebSecurityManager.setRealm(myRealm);//將CookieRememberMeManager對象注入到SecurityManager,開啟了rememberme功能defaultWebSecurityManager.setCacheManager(ehCacheManager());return defaultWebSecurityManager;}//設置Cookie的信息public SimpleCookie rememberMeCookie(){SimpleCookie simpleCookie=new SimpleCookie("rememberMe");//設置有效路徑simpleCookie.setPath("/");//設置聲明周期simpleCookie.setMaxAge(30*24*60*60);//返回設置的cookiereturn simpleCookie;}//創建rememberMeManager對象public CookieRememberMeManager rememberMeManager(){//創建CookieRememberMeManager對象CookieRememberMeManager cookieRememberMeManager=new CookieRememberMeManager();//注入Cookie對象cookieRememberMeManager.setCookie(rememberMeCookie());//設置密鑰cookieRememberMeManager.setCipherKey(Base64.decode("MTIzNDU2Nzg="));//返回return cookieRememberMeManager;}//自定義shiro過濾器參數bean----`definition.addPathDefinition("/**", "user");`@Beanpublic ShiroFilterChainDefinition shiroFilterChainDefinition(){DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();definition.addPathDefinition("/login", "anon");definition.addPathDefinition("/userLogin2", "anon");//開啟shiro內置的退出過濾器,完成退出功能definition.addPathDefinition("/logout", "logout");//definition.addPathDefinition("/main", "anon");definition.addPathDefinition("/**", "user");return definition;}四、 配置退出
1 修改配置類
修改ShiroConfig類,添加logout filter 對應的url。definition.addPathDefinition("/logout", "logout");
@Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();definition.addPathDefinition("/doLogin", "anon");definition.addPathDefinition("/logout", "logout");definition.addPathDefinition("/**", "authc");return definition; }2 修改主頁面
在index.html頁面中添加超鏈接。跳轉到/logout后會由shiro內置filter進行攔截。
<body> index.html <a href="/logout">退出</a> </body>五、 授權
1 簡介
授權就是判斷認證用戶是否具有指定角色或指定權限。
Shiro可以和JSP整合也可以和Thymeleaf整合,我們講解SpringBoot的視圖技術Thymeleaf整合Shiro。
只要是授權就執行Realm的doGetAuthorizationInfo進行判斷,而觸發doGetAuthorizationInfo的方式,常用的就兩種:
(1)在頁面中通過shiro:xxxx 屬性進行判斷
(2)在java代碼中通過注解@RequiresXXX
thymeleaf中常用屬性
需要在html頁面中添加屬性
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">1.1 shiro:user=””
認證通過或已記住的用戶。
1.2 shiro:authenticated=””
認證通過的用戶。不包含記住的用戶。
1.3 shiro:principal
輸出認證用戶信息。shiro:principal/
1.4 shiro:hasRole=“admin”
判斷是否具有指定角色。
1.5 shiro:lacksRole=“admin”
判斷是否不是沒有指定角色。
1.6 shiro:hasAllRoles=“role1,role2”
判斷指定角色用戶是否都具有。
1.7 shiro:hasAnyRoles=“role1,role2”
只要用戶具有其中一個角色就表示判斷通過。
1.8 shiro:hasPermission=“userInfo:add”
是否具有指定權限。
1.9 shiro:lacksPermission=“userInfo:del”
是否不具有指定權限
1.10 shiro:hasAllPermissions=“userInfo:view, userInfo:add”
是否全具有指定權限。
1.11 shiro:hasAnyPermissions=“userInfo:view, userInfo:del”
只要有其中任何一個權限即可。
2 Thymeleaf整合shiro
2.1 添加依賴
<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version> </dependency>2.2 修改配置類(負責解析thymeleaf中shiro的相關屬性)
//創建解析Thymeleaf中的shiro屬性的對象,由SpringBoot項目底層自動調用@Beanpublic ShiroDialect shiroDialect() {return new ShiroDialect();}2.3 修改Realm
綁定用戶具有的角色和權限,相關數據應該是從數據庫中取出。
//自定義授權策略@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//1.從數據庫中獲取用戶的權限信息//2.將權限信息存儲到shiro授權對象中System.out.println("我是授權認證方法,我被執行了");SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();info.addRole("role1");info.addRole("role2");info.addStringPermission("user:insert");info.addStringPermission("user:update");info.addStringPermission("sys:*");return info;}2.4 修改main.html
訪問頁面后會發現“有角色”不顯示,“有權限”顯示。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head><meta charset="UTF-8"><title>Title</title> </head> <body>我是主頁面<a href="/logout">退出</a><hr><span shiro:hasRole="role3">有角色</span><br><span shiro:user="">shiro:user=””認證通過或已記住的用戶</span><br><span shiro:authenticated="">shiro:authenticated=””認證通過的用戶。不包含記住的用戶。</span><br><hr><a href="/demo">測試后臺邏輯代碼的授權</a></body> </html>3 使用注解判斷方法是否具有權限執行
方法:可以用控制器方法,也可以是業務方法。常在控制器方法上添加注解進行判斷。
常用注解:
(1)@RequiresPermissions("") 必須具有指定權限
(2)@RequiresAuthentication 必須已經認證
(3)@RequiresRoles("") 必須具有指定角色
(4)@RequiresUser 必須是已認證或記住用戶
(5)@RequiresGuest 必須是訪客
3.1 修改main.html
添加下面內容
<a href="/isPermission">跳轉到判斷權限的控制器</a>3.2 修改UserController類
@RequestMapping("/isPermission") @ResponseBody @RequiresPermissions("abc:jqk") public String isPermission(){return "OK"; }當用戶登錄成后,點擊超鏈接“跳轉到判斷權限的”超鏈接會出現500錯誤頁面信息。
3.3 新建依賴處理類
新建com.bjsxt.controller.NoPermissionException
@ControllerAdvice public class NoPermissionException {@ResponseBody@ExceptionHandler(UnauthorizedException.class)public String handleShiroException(Exception ex) {return "無權限";}@ResponseBody@ExceptionHandler(AuthorizationException.class)public String AuthorizationException(Exception ex) {return "權限認證失敗";} }六 EHCache
1 ehcache簡介
EHCache是sourceforge的開源緩存項目,現已經具有獨立官網,網址:(http://www.ehcache.org)。其本身是純JAVA實現的,所以可以和絕大多數Java項目無縫整合,例如:Hibernate的緩存就是基于EHCache實現的。
EHCache支持內存和磁盤緩存,默認是存儲在內存中的,當內存不夠時允許把緩存數據同步到磁盤中,所以不需要擔心內存不夠問題。
EHCache支持基于Filter的Cache實現,同時也支持Gzip壓縮算法提高響應速度。
2 EHCache API演示
2.1 添加依賴
從3.0版本開始groupid為org.ehcache
<dependencies><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>2.6.11</version></dependency> </dependencies>2.2 新建配置文件
在src/main/resources中新建ehcache.xml。
屬性含義:
maxElementsInMemory:緩存中允許創建的最大對象數。
eternal:緩存中對象是否為永久的,如果是,超時設置將被忽略,對象從不過期。
timeToIdleSeconds:緩存數據的鈍化時間,取值0表示無限長。
timeToLiveSeconds:緩存數據的生存時間,取值0表示無限長。
overflowToDisk:內存不足時,是否啟用磁盤緩存。
memoryStoreEvictionPolicy:緩存滿了之后的淘汰算法。
七 Shiro和EhCache整合
Shiro支持很多第三方緩存工具。官方提供了shiro-ehcache,實現了把EHCache當做Shiro的緩存工具的解決方案。其中最好用的一個功能是就是緩存認證執行的Realm方法,減少對數據庫的訪問。
1 添加依賴
添加shiro-ehcache依賴。
commons-io主要是為了使用里面的工具類。本質和當前整合功能沒有關系。
2 編寫ehcache緩存配置
在resources下新建ehcache/ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="ehcache" updateCheck="false"><!-- 磁盤緩存位置 --> <diskStore path="java.io.tmpdir"/> <!-- 默認緩存 --> <defaultCachemaxEntriesLocalHeap="1000"eternal="false"timeToIdleSeconds="3600"timeToLiveSeconds="3600"overflowToDisk="false"> </defaultCache><!-- 登錄記錄緩存 鎖定10分鐘 --> <cache name="loginRecordCache"maxEntriesLocalHeap="2000"eternal="false"timeToIdleSeconds="600"timeToLiveSeconds="0"overflowToDisk="false"statistics="true"> </cache></ehcache>3 修改配置文件
@Bean public DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager manager = new DefaultWebSecurityManager();HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("md5");hashedCredentialsMatcher.setHashIterations(2);myRealm.setCredentialsMatcher(hashedCredentialsMatcher);manager.setRealm(myRealm);manager.setRememberMeManager(rememberMeManager());manager.setCacheManager(getEhCacheManager());return manager; }@Bean public EhCacheManager ehCacheManager(){EhCacheManager ehCacheManager = new EhCacheManager();InputStream is = null;try {is = ResourceUtils.getInputStreamForPath("classpath:ehcache/ehcache-shiro.xml");} catch (IOException e) {e.printStackTrace();}net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager(is);ehCacheManager.setCacheManager(cacheManager);return ehCacheManager; }八 Shiro中Session對象獲取
Session session = SecurityUtils.getSubject().getSession(); session.setAttribute("key","value");總結
以上是生活随笔為你收集整理的SpringBoot整合Shiro实现登录认证和授权CHCache的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑开机后卡主板LOGO界面不进系统电脑
- 下一篇: SpringSecurity认证