官网
Shiro是一款主流的java安全框架,不依赖任何容器可以运行在javase和javaee项目中,它的主要作用
是访问系统的用户进行身份认证,授权,会话管理,加密等操作
Shiro就是用来解决安全管理的系统化框架
-- MySQL dump 10.13 Distrib 8.0.19, for Win64 (x86_64)
--
-- Host: 127.0.0.1 Database: test
-- ------------------------------------------------------
-- Server version 8.0.19
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `account`
--
DROP TABLE IF EXISTS `account`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `account` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`perms` varchar(20) DEFAULT NULL,
`role` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `account`
--
LOCK TABLES `account` WRITE;
/*!40000 ALTER TABLE `account` DISABLE KEYS */;
INSERT INTO `account` VALUES (1,'zs','123123','',''),(2,'ls','123123','manage','administrator'),(3,'ww','123123','','');
/*!40000 ALTER TABLE `account` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-06-04 14:10:15
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bd13</groupId>
<artifactId>springboot-shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-shiro</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--shiro依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<!--Shiro 整合 Thymeleaf 依赖-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 09301225
url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
package com.bd13.springbootshiro.entity;
public class Account {
private Integer id;
private String username;
private String password;
private String perms;
private String role;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPerms() {
return perms;
}
public void setPerms(String perms) {
this.perms = perms;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
package com.bd13.springbootshiro.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bd13.springbootshiro.entity.Account;
public interface AccountMapper extends BaseMapper<Account> {
}
package com.bd13.springbootshiro.service;
import com.bd13.springbootshiro.entity.Account;
public interface AccountService {
public Account findByUsername(String username);
}
package com.bd13.springbootshiro.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bd13.springbootshiro.entity.Account;
import com.bd13.springbootshiro.mapper.AccountMapper;
import com.bd13.springbootshiro.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public Account findByUsername(String username) {
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("username",username);
return accountMapper.selectOne(wrapper);
}
}
package com.bd13.springbootshiro.realm;
import com.bd13.springbootshiro.entity.Account;
import com.bd13.springbootshiro.service.AccountService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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 java.util.HashSet;
import java.util.Set;
public class AccountRealm extends AuthorizingRealm {
@Autowired
private AccountService accountService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取当前登录的用户信息
Subject subject= SecurityUtils.getSubject();
Account account = (Account) subject.getPrincipal();
//设置角色
Set<String> roles=new HashSet<>();
roles.add(account.getRole());
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles);
//设置权限
info.addStringPermission(account.getPerms());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
Account account = accountService.findByUsername(token.getUsername());
if (account != null){
return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
}
return null;
}
}
package com.bd13.springbootshiro.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.bd13.springbootshiro.realm.AccountRealm;
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 java.util.Hashtable;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//权限设置
Map<String,String> map=new Hashtable<>();
map.put("/main","authc");
// map.put("/manage","perms[manage]");
// map.put("/administrator","roles[administrator]");
factoryBean.setFilterChainDefinitionMap(map);
//设置登录页面
factoryBean.setLoginUrl("/login");
//设置未授权页面
factoryBean.setUnauthorizedUrl("/unaurh");
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("accountRealm") AccountRealm accountRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(accountRealm);
return manager;
}
@Bean
public AccountRealm accountRealm(){
return new AccountRealm();
}
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
}
package com.bd13.springbootshiro.controller;
import com.bd13.springbootshiro.entity.Account;
import org.apache.shiro.SecurityUtils;
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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class AccountController {
@GetMapping("/{url}")
public String redirect(@PathVariable("url")String url){
return url;
}
@PostMapping("/login")
public String login(String username, String password, Model model){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
subject.login(token);
Account account= (Account) subject.getPrincipal();
subject.getSession().setAttribute("account",account);
return "index";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误!");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误!");
return "login";
}
}
@GetMapping("/unauth")
@ResponseBody
public String unauth(){
return "未授权,无法访问!";
}
@GetMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
}
}
login.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="shortcut icon" href="#"/>
head>
<body>
<form action="/login" method="post">
<table>
<span th:text="${msg}" style="color: red">span>
<tr>
<td>用户名:td>
<td>
<input type="text" name="username"/>
td>
tr>
<tr>
<td>密码:td>
<td>
<input type="password" name="password"/>
td>
tr>
<tr>
<td>
<input type="submit" value="登录"/>
td>
tr>
table>
form>
body>
html>
index.html
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="shortcut icon" href="#"/>
head>
<body>
<h1>indexh1>
<div th:if="${session.account != null}">
<span th:text="${session.account.username}+'欢迎回来!'">span><a href="/logout">退出a>
div>
<a href="/main">maina> <br/>
<div shiro:hasPermission="manage">
<a href="manage">managea> <br/>
div>
<div shiro:hasRole="administrator">
<a href="/administrator">administratora>
div>
body>
html>
main.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="shortcut icon" href="#"/>
head>
<body>
<h1>mainh1>
body>
html>
manage.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="shortcut icon" href="#"/>
head>
<body>
<h1>manageh1>
body>
html>
administrator.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="shortcut icon" href="#"/>
head>
<body>
<h1>administatorh1>
body>
html>
代码下载地址