springboot+shiro+thymeleaf整合
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</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.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--mysql数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--thymeleaf引擎模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--thymeleaf shiro整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!--jquery-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
<!-- mybatis逆向工程jar包 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--热部署依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
配置项目
server.port=8085
#数据库连接配置
spring.datasource.url=jdbc:mysql://ip:3306/sweetinn?characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#mybatis整合
mybatis.type-aliases-package=springbootshiro.pojo
mybatis.mapper-locations= classpath:mapper/*.xml
#关闭thymeleaf缓存
spring.thymeleaf.cache=false
创建自定义UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
SysUserService sysUserService;
@Autowired
AuthoritiesService authoritiesService;
@Autowired
SysRoleService sysRoleService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//info.addStringPermission("level"); //这里都是从数据库取的
Subject subject = SecurityUtils.getSubject();
SysUser user = (SysUser)subject.getPrincipal(); //认证SimpleAuthenticationInfo的第一个参数
//为用户授权
List<Authorities> authorities = authoritiesService.findAuthoritiesByUserId(user.getId());
for (Authorities authoritie:authorities) {
info.addStringPermission(authoritie.getAuthority());
}
//为用户添加角色
List<SysRole> sysRoles = sysRoleService.findSysRoleByUserId(user.getId());
for (SysRole sysRole:sysRoles) {
info.addRole(sysRole.getRoleName());
}
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证方法doGetAuthenticationInfo");
UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
SysUser sysUser = sysUserService.findSysUserByNameAndPassword(token.getUsername(),String.valueOf(token.getPassword()));
if(sysUser==null){
return null; //抛出UnknownAccountException异常
}
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
session.setAttribute("user",sysUser);
//密码认证
return new SimpleAuthenticationInfo(sysUser,sysUser.getPassword(),getName());
}
}
添加shiro配置
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean factoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器
/*anon:都可以访问
authc:必须认证才能访问
user:必须拥有记住我这个功能才能访问
perms[]:拥有对某个资源的权限才能访问
roles[]:拥有某个角色权限才能访问
*/
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被拦截
filterChainDefinitionMap.put("/toLogin", "anon");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/index", "anon");
// 配置会被拦截
filterChainDefinitionMap.put("/level1/**", "roles[level1]");
filterChainDefinitionMap.put("/level2/**", "roles[level2]");
filterChainDefinitionMap.put("/level3/**", "roles[level3]");
filterChainDefinitionMap.put("/level4/add","perms[level4:add]");
filterChainDefinitionMap.put("/level4/update","perms[level4:update]");
filterChainDefinitionMap.put("/level4/**", "roles[level4]");
//剩余的路径都需要授权
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//设置登录的请求页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
// 首页
shiroFilterFactoryBean.setSuccessUrl("/index");
//设置未授权提示页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
return shiroFilterFactoryBean;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userRealm);
return manager;
}
//创建自定义UserRealm
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//整合shiro-thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
controller
@Controller
public class IndexController {
@RequestMapping({"/","/index"})
public String home(String name, String passwd, Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户登录数据
UsernamePasswordToken token = new UsernamePasswordToken(name,passwd);
try{
subject.login(token);//执行认证方法
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名或密码错误");
return "mylogin";
}catch(IncorrectCredentialsException e){
model.addAttribute("msg", "密码错误");
return "mylogin";
} catch (AuthenticationException e) {
model.addAttribute("msg", "登录失败");
return "mylogin";
}
return "home/home";
}
@RequestMapping("/toLogin")
public String login(){
return "mylogin";
}
@RequestMapping("/logout")
public String logout(){
SecurityUtils.getSubject().logout();
return "mylogin";
}
@RequestMapping("/unauthorized")
public String unauthorized(){
return "unauthorized";
}
@RequestMapping("/level1/page/{id}")
public String level1(@PathVariable("id") int id){
return "level1/page"+id;
}
@RequestMapping("/level2/page/{id}")
public String level2(@PathVariable("id") int id){
return "level2/page"+id;
}
@RequestMapping("/level3/page/{id}")
public String level3(@PathVariable("id") int id){
return "level3/page"+id;
}
@RequestMapping("/level4/page/{id}")
public String level4(@PathVariable("id") int id){
return "level4/page"+id;
}
@RequestMapping("/level4/update")
public String level4Update(){
return "level4/update";
}
@RequestMapping("/level4/add")
public String level4Add(){
return "level4/add";
}
}
前端页面
登录页mylogin.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<p th:text="${msg}" style="color: red"></p>
<div style="text-align: center">
登录
<form th:action="@{/index}" method="post">
登录名:<input name="name" /> <br/>
密码:<input type="password" name="passwd"/><br/>
<input type="submit" />
</form>
</div>
</body>
</html>
主页home.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<div th:if="${session.user==null}">
<a th:href="@{/toLogin}">登录</a>
</div>
<div th:if="${session.user!=null}">
<a th:href="@{/logout}">注销</a>
</div>
</div>
<div shiro:hasAnyRoles="level1">
<a th:href="@{/level1/page/1}">level1-page1</a>
<a th:href="@{/level1/page/2}">level1-page2</a>
<a th:href="@{/level1/page/3}">level1-page3</a>
</div>
<div shiro:hasAnyRoles="level2">
<a th:href="@{/level2/page/1}">level2-page1</a>
<a th:href="@{/level2/page/2}">level2-page2</a>
<a th:href="@{/level2/page/3}">level2-page3</a>
</div>
<div shiro:hasAnyRoles="level3">
<a th:href="@{/level3/page/1}">level3-page1</a>
<a th:href="@{/level3/page/2}">level3-page2</a>
<a th:href="@{/level3/page/3}">level3-page3</a>
</div>
<div shiro:hasAnyRoles="level4">
<a th:href="@{/level4/page/1}">level4-page1</a>
</div>
</body>
</html>
未授权提示页面unauthorized.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
访问页面未授权
</body>
</html>
level1/page1.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level1-page1
</body>
</html>
level1/page2.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level1-page2
</body>
</html>
level1/page3.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level1-page3
</body>
</html>
level2/page1.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level2-page1
</body>
</html>
level2/page2.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level2-page2
</body>
</html>
level2/page3.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level2-page3
</body>
</html>
level3/page1.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level3-page1
</body>
</html>
level3/page2.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level3-page2
</body>
</html>
level3/page3.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level3-page3
</body>
</html>
level4/page1.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level4-page1<br/>
<div shiro:hasPermission="level4:add">
<a th:href="@{/level4/add}">添加</a>
</div>
<div shiro:hasPermission="level4:update">
<a th:href="@{/level4/update}">修改</a>
</div>
</body>
</html>
level4/add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level4add
</body>
</html>
level4/update.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
level4update
</body>
</html>