本篇框架使用:SpringBoot SpringMvc MyBatis shiro thymeleaf 我們先來了解一下shiro的基本知識(shí)
1.什么是Shiro權(quán)限框架 Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份認(rèn)證,、授權(quán),、加密和會(huì)話管理,。使用Shiro的易于理解的API,可以快速,、輕松地獲得任何應(yīng)用程序,,從最小的移動(dòng)應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序,。 2.Shiro可以做哪些事情 ●驗(yàn)證用戶身份 ●用戶訪問控制,比如用戶是否被賦予了某個(gè)角色;是否允許訪問某些資源 ●在任何環(huán)境都可以使用SessionAPI,即使不是WEB項(xiàng)目或沒有EJB容器 ●事件響應(yīng)(在身份驗(yàn)證,,訪問控制期間,,或是session生命周期中) ●集成多種用戶信息數(shù)據(jù)源 ●SSO- 單點(diǎn)登陸 ●Remember Me,記住我 ●Shiro嘗試在任何應(yīng)用環(huán)境下實(shí)現(xiàn)這些功能,,而不依賴其他框架,、容器或應(yīng)用服務(wù)器。 3.Shiro與Springsecurity區(qū)別 1.首先Shiro較之Spring Security, Shiro 在保持強(qiáng)大功能的同時(shí),還在簡(jiǎn)單性和靈活性方面擁有巨大優(yōu)勢(shì),。 2.Shiro是一個(gè)強(qiáng)大而靈活的開源安全框架,,能夠非常清晰的處理認(rèn)證、授權(quán),、加密,、會(huì)話管理等功能。 3.密碼加密
4.框架體系 Shiro 的整體框架大致如下圖所示(圖片來自互聯(lián)網(wǎng)):
Authentication(認(rèn)證), Authorization(授權(quán)), Session Management(會(huì)話管理), Cryptography(加密)代表Shiro應(yīng)用安全的四大基石,。
它們分別是: Authentication(認(rèn)證):用戶身份識(shí)別,,通常被稱為用戶“登錄”。 Authorization(授權(quán)):訪問控制,。比如某個(gè)用戶是否具有某個(gè)操作的使用權(quán)限,。 Session Management(會(huì)話管理):特定于用戶的會(huì)話管理,甚至在非web 應(yīng)用程序。 Cryptography(加密):在對(duì)數(shù)據(jù)源使用加密算法加密的同時(shí),,保證易于使用,。 除此之外,還有其他的功能來支持和加強(qiáng)這些不同應(yīng)用環(huán)境下安全領(lǐng)域的關(guān)注點(diǎn),。 特別是對(duì)以下的功能支持: Web支持:Shiro 提供的 web 支持 api ,,可以很輕松的保護(hù) web 應(yīng)用程序的安全。 緩存:緩存是 Apache Shiro 保證安全操作快速,、高效的重要手段,。 并發(fā):Apache Shiro 支持多線程應(yīng)用程序的并發(fā)特性。 測(cè)試:支持單元測(cè)試和集成測(cè)試,,確保代碼和預(yù)想的一樣安全,。 “Run As”:這個(gè)功能允許用戶在許可的前提下假設(shè)另一個(gè)用戶的身份。 “Remember Me”:跨 session 記錄用戶的身份,,只有在強(qiáng)制需要時(shí)才需要登錄,。 5.shiro主要流程 在概念層,Shiro 架構(gòu)包含三個(gè)主要的理念:Subject, SecurityManager 和 Realm,。下面的圖展示了這些組件如何相互作用,,我們將在下面依次對(duì)其進(jìn)行描述。
1.Subject:當(dāng)前用戶,,Subject 可以是一個(gè)人,但也可以是第三方服務(wù),、守護(hù)進(jìn)程帳戶,、時(shí)鐘守護(hù)任務(wù)或者其它-當(dāng)前和軟件交互的任何事件。 2. SecurityManager:管理所有Subject,,SecurityManager 是Shiro 架構(gòu)的核心,,配合內(nèi)部安全組件共同組成安全傘。 3.Realms:用于進(jìn)行權(quán)限信息的驗(yàn)證,,我們自己實(shí)現(xiàn),。Realm本質(zhì)上是一個(gè)特定的安全DAO:它封裝與數(shù)據(jù)源連接的細(xì)節(jié),,得到Shiro所需的相關(guān)的數(shù)據(jù)。在配置Shiro的時(shí)候,,你必須指定至少一個(gè)Realm來實(shí)現(xiàn)認(rèn)證(authentication)和/或授權(quán)( authorization),。
了解完shiro的基礎(chǔ)知識(shí),接下來我們看代碼的實(shí)現(xiàn)
數(shù)據(jù)庫表
user表
role表
代碼目錄結(jié)構(gòu)
pom.xml(加入shiro依賴包)
<dependencies>
<!--包含spirng Mvc ,tomcat的包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https:///artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<!-- 包含spirng Mvc ,tomcat的包包含requestMapping restController 等注解 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis 與 spring boot 2.x的整合包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!-- 連接mysql數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
<!-- mysql包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
配置類application.properties(配置連接mysql數(shù)據(jù)庫,,mybatis,thymeleaf配置)
server.port=8080
#數(shù)據(jù)庫連接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#mybatis配置
mybatis.type-aliases-package=com.demo.shiro.entity
mybatis.mapper-locations=classpath:mapper/*.xml
# thymeleaf頁面模板配置
spring.thymeleaf.prefix= classpath:/templates/
spring.thymeleaf.suffix=.ftl
項(xiàng)目啟動(dòng)類ShiroApplication(對(duì)mapper進(jìn)行掃包)
package com.demo.shiro;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = "com.demo.shiro.mapper")
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class, args);
}
}
實(shí)體類RoleMapper
/*******************************************************************************
* Package: com.demo.shiro.entity
* Type: RoleEntity
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.entity;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* 角色實(shí)體
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
@Data
@Getter
@Setter
public class RoleEntity {
private Integer id;
private String role;
private String permissionurl;
public RoleEntity(){};
public RoleEntity(Integer id, String role, String permissionurl) {
this.id = id;
this.role = role;
this.permissionurl = permissionurl;
}
}
實(shí)體類UserMapper
/*******************************************************************************
* Package: com.demo.shiro.entity
* Type: UserEntity
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.entity;
import jdk.nashorn.internal.objects.annotations.Constructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* 用戶實(shí)體
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
@Data
@Getter
@Setter
public class UserEntity {
private int id;
private String userName;
private String realName;
private String passWord;
private String role;
public UserEntity(){}
public UserEntity(int id, String userName, String realName, String passWord, String role) {
this.id = id;
this.userName = userName;
this.realName = realName;
this.passWord = passWord;
this.role = role;
}
}
RoleMapper類
/*******************************************************************************
* Package: com.demo.shiro.mapper
* Type: RoleMapper
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.mapper;
import com.demo.shiro.entity.RoleEntity;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* TODO your comment
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
@Repository
public interface RoleMapper {
/**
* 查詢所有角色表信息
* @return
*/
List<RoleEntity> selectRoleAll();
}
UserMapper類
/*******************************************************************************
* Package: com.demo.shiro.mapper
* Type: UserMapper
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.mapper;
import com.demo.shiro.entity.UserEntity;
import org.apache.ibatis.annotations.Param;
/**
* 根據(jù)用戶名查詢數(shù)據(jù)
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
public interface UserMapper {
UserEntity findByUsername(@Param(value = "userName") String userName);
}
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "http:///dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.demo.shiro.mapper.RoleMapper">
<select id="selectRoleAll" resultType="com.demo.shiro.entity.RoleEntity">
SELECT
*
FROM
test.ROLE
</select>
</mapper>
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "http:///dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.demo.shiro.mapper.UserMapper">
<select id="findByUsername" resultType="com.demo.shiro.entity.UserEntity">
SELECT
u.id,
u.user_name AS userName,
u.real_name AS realName,
u.PASSWORD,
u.role
FROM
test.USER u
WHERE
u.user_name = #{userName}
</select>
</mapper>
ShiroConfig配置類(項(xiàng)目啟動(dòng)時(shí)加載,,配置頁面登錄攔截,登錄權(quán)限)
/*******************************************************************************
* Package: com.demo.shiro.config
* Type: ShiroConfig
* Date: 2020/12/5 10:44
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.config;
import com.demo.shiro.entity.RoleEntity;
import com.demo.shiro.mapper.RoleMapper;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.List;
/**
* ShiroConfig
*
* @author Yujiaqi
* @date 2020/12/5 10:44
*/
@Configuration
public class ShiroConfig {
@Autowired
private MayiktRealm mayiktRealm;
@Autowired
private RoleMapper roleMapper;
/**
* @Configuration實(shí)際上就是@Component,,將類注入到spring容器中
*/
/**
* 配置shiroFilter
* @param securityManager
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//設(shè)定登錄頁面
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/home");
HashMap<String, String> map = new HashMap<>();
//不需要登錄,,就可以訪問接口
map.put("/mayiktOpenApi","anon");
//需要要登錄才可以訪問該接口,采用彈框的形式(authcBasic),表單模式(authc)
//要跳轉(zhuǎn)到home頁面的用戶必須經(jīng)過登錄
map.put("/home","authc");
// //設(shè)定order接口只能order角色訪問
// map.put("/order/*","roles[order]");
// //設(shè)定member接口只能member角色訪問
// map.put("/member/*","roles[member]");
//通過數(shù)據(jù)庫設(shè)計(jì)接口訪問權(quán)限
List<RoleEntity> roleEntities = roleMapper.selectRoleAll();
roleEntities.forEach(t -> {
map.put(t.getPermissionurl(),"roles[" t.getRole() "]");
});
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(){
//將自定義Realm加進(jìn)來
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(mayiktRealm);
return securityManager;
}
}
MayiktRealm類 需要繼承AuthorizingRealm類
/*******************************************************************************
* Package: com.demo.shiro.config
* Type: MayiktRealm
* Date: 2020/12/5 10:59
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.config;
import com.alibaba.druid.util.StringUtils;
import com.demo.shiro.entity.UserEntity;
import com.demo.shiro.mapper.UserMapper;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.HashSet;
/**
* 配置攔截器
*
* @author Yujiaqi
* @date 2020/12/5 10:59
*/
@Component
public class MayiktRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
/**
* 為當(dāng)前登錄成功的用戶授予權(quán)限和分配角色,。
* 在用戶登錄成功后,,每次請(qǐng)求后臺(tái)接口都需要先訪問此方法,進(jìn)行權(quán)限的驗(yàn)證
* @param principal
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
String username = (String)principal.getPrimaryPrincipal();
UserEntity byUsername = userMapper.findByUsername(username);
if (byUsername == null){
return null;
}
String role = byUsername.getRole();
if (StringUtils.isEmpty(role)){
return null;
}
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//設(shè)置權(quán)限
HashSet<String> roles = new HashSet<>();
String[] split = role.split(",");
Arrays.stream(split).forEach(t ->{
roles.add(t);
});
//設(shè)置我們的權(quán)限
simpleAuthorizationInfo.setRoles(roles);
return simpleAuthorizationInfo;
}
/**
* 用來驗(yàn)證當(dāng)前登錄的用戶,,獲取認(rèn)證信息,。
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
String userName = (String) authenticationToken.getPrincipal();
if (userName == null){
return null;
}
UserEntity byUsername = userMapper.findByUsername(userName);
if(byUsername == null){
return null;
}
//使用數(shù)據(jù)庫db的密碼驗(yàn)證用戶輸入的密碼
//這里傳入的password(這里是從數(shù)據(jù)庫獲取的)和token(filter中登錄時(shí)生成的)中的password做對(duì)比,如果相同就允許登錄,,不相同就拋出異常,。
SimpleAuthenticationInfo simpleAuthorizationInfo = new SimpleAuthenticationInfo(userName, byUsername.getPassWord(), byUsername.getRealName());
return simpleAuthorizationInfo;
}
}
MD5Util類(進(jìn)行密碼加密)
/*******************************************************************************
* Package: com.demo.shiro.config
* Type: MD5Util
* Date: 2020/12/5 11:05
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.config;
import java.security.MessageDigest;
/**
* 用于密碼加密
*
* @author Yujiaqi
* @date 2020/12/5 11:05
*/
public class MD5Util {
private static final String SALT = "yujiaqi";
public static String encode(String password) {
password = password SALT;
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
throw new RuntimeException(e);
}
char[] charArray = password.toCharArray();
byte[] byteArray = new byte[charArray.length];
for (int i = 0; i < charArray.length; i )
byteArray[i] = (byte) charArray[i];
byte[] md5Bytes = md5. digest( byteArray);
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes. length; i ) {
int val = ((int) md5Bytes[i]) & 0xff;
if(val<16){
hexValue . append("0");
}
hexValue.append(Integer. toHexString(val));
}
return hexValue. toString();
}
public static void main(String[] args) {
System.out.println(encode("123456"));
//密碼只能加密,不能解密,,只能通過暴力破解
}
}
IndexController登錄入口類
/*******************************************************************************
* Package: com.demo.shiro.controller
* Type: IndexController
* Date: 2020/12/5 10:49
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* IndexController
*
* @author Yujiaqi
* @date 2020/12/5 10:49
*/
@Controller
public class IndexController {
@RequestMapping("/home")
public String home(){
return "home";
}
@ResponseBody
@RequestMapping("/mayiktOpenApi")
public String mayikt(){
return "不需要任何登錄和權(quán)限都可以訪問到";
}
@ResponseBody
@RequestMapping("/unauthorized")
public String unauthorized(){
return "你的角色暫時(shí)沒有該權(quán)限,,無法訪問該接口";
}
}
LoginController類
/*******************************************************************************
* Package: com.demo.shiro.controller
* Type: LoginController
* Date: 2020/12/5 13:54
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.controller;
import com.demo.shiro.config.MD5Util;
import com.demo.shiro.entity.UserEntity;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* TODO your comment
*
* @author Yujiaqi
* @date 2020/12/5 13:54
*/
@Controller
public class LoginController {
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("userLogin")
public String userLogin(UserEntity userEntity, Model model){
// 獲取主題用戶
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userEntity.getUserName(),
MD5Util.encode(userEntity.getPassWord()));
try{
//登錄就會(huì)走M(jìn)ayiktRealm.doGetAuthenticationInfo方法驗(yàn)證用戶名密碼
subject.login(usernamePasswordToken);
model.addAttribute("userName" , userEntity.getUserName());
return "home";
}catch (IncorrectCredentialsException e){
e.printStackTrace();
model.addAttribute("error","賬號(hào)密碼錯(cuò)誤!");
return "login";
}
}
}
MemberController類
/*******************************************************************************
* Package: com.demo.shiro.controller
* Type: MemberController
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* TODO your comment
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
@RestController
@RequestMapping("/member")
public class MemberController {
@RequestMapping("getMember")
public String getMember(){
return "getMember";
}
@RequestMapping("insertMember")
public String insertMember(){
return "insertMember";
}
}
OrderController類
/*******************************************************************************
* Package: com.demo.shiro.controller
* Type: OrderController
* Date: 2020/12/5 11:06
*
* Copyright (c) 2020 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
*
* You may not use this file except in compliance with the License.
*******************************************************************************/
package com.demo.shiro.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* TODO your comment
*
* @author Yujiaqi
* @date 2020/12/5 11:06
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@RequestMapping("insertOrder")
public String insertOrder(){
return "insertOrder";
}
@RequestMapping("updateOrder")
public String updateOrder(){
return "updateOrder";
}
@RequestMapping("deleteOrder")
public String deleteOrder(){
return "deleteOrder";
}
}
前端頁面
home.ftl
<html xmlns:th="http://www.">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>Insert title here</title>
</head>
<body>
<h1>恭喜您進(jìn)入到管理系統(tǒng)<span th:text="${userName}"></span></h1>
<h3><a href="/order/insertOrder">insertOrder</a></h3>
<h3><a href="/order/updateOrder">updateOrder</a></h3>
<h3><a href="/order/deleteOrder">deleteOrder</a></h3>
<h3><a href="/member/insertMember">insertMember</a></h3>
<h3><a href=" /member/getMember" >getMember</a></h3>
</body>
</html>
login.ftl
<html xmlns:th="http://www.">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>Insert title here</title>
</head>
<body>
<h1>每特教育--權(quán)限控制登陸系統(tǒng)</h1>
<form action="/userLogin" method="post">
<span>用戶名稱:</span><input type= "text" name="userName"/><br>
<span>用戶密碼:</span><input type="password" name= "passWord"/><br>
<input type="submit" value="登陸" >
</form>
<span style="color: red" th:text="${error}"></span>
</body>
</html>
ShiroConfig類為啟動(dòng)時(shí)加載
我們?cè)L問
我們?cè)L問127.0.0.1:8080/home就會(huì)進(jìn)入到
我們輸入錯(cuò)誤的用戶名密碼進(jìn)行登錄:會(huì)進(jìn)入到doGetAuthenticationInfo方法用來驗(yàn)證當(dāng)前登錄的用戶,,獲取認(rèn)證信息,。用戶名密碼正確登錄成功,否則登錄失敗,,并且后臺(tái)會(huì)報(bào)錯(cuò)
下面我們輸入正確的用戶名密碼(登錄成功)
我們登錄的是yujiaqi_admin用戶,,他的權(quán)限為member,order,意思是我們可以訪問/member/*接口也可以訪問/order/*接口
接下來我們點(diǎn)擊insertOrder(訪問成功),,會(huì)調(diào)用doGetAuthorizationInfo方法為當(dāng)前登錄成功的用戶授予權(quán)限和分配角色,。 在用戶登錄成功后,每次請(qǐng)求后臺(tái)接口都需要先訪問此方法,,進(jìn)行權(quán)限的驗(yàn)證
點(diǎn)擊insertMember(訪問成功)
其他訪問類似
接下來我們登錄yujiaqi_order用戶,,他的權(quán)限order說明mayikt_order用戶,只能訪問/order/*接口
我們點(diǎn)擊insertOrder(訪問成功)
點(diǎn)擊insertMember(訪問失敗,,沒有權(quán)限)
到此我們就完成了shiro安全框架的整合,,可以進(jìn)行登錄攔截,也可以給用戶進(jìn)行權(quán)限的分配
博主也是初學(xué)shiro框架,后續(xù)還會(huì)有Shiro整合Jwt實(shí)現(xiàn)前后端分離,,Shiro整合0auth2實(shí)現(xiàn)權(quán)限認(rèn)證正在學(xué)習(xí),,希望留下你的小心心
想當(dāng)年我們也是在道上混的,只不過后來改邪歸正了
?
?
來源:https://www./content-4-777501.html
|