SpringBoot整合Shiro
文章目录
前言
创建项目版本:2.3.5.RELEASE;
开发工具:idea2019.1;
jdk版本:1.8;
简单理解Springboot集成Shiro的项目,实际生产项目中还需要考虑更多。
项目代码:https://github.com/lwd2307997664/demoShiro.git
一、Shiro简介
Apache Shiro 是一个功能强大且灵活的开放源代码安全框架,可以细粒度地处理认证 (Authentication),授权 (Authorization),会话 (Session) 管理和加密 (cryptography) 等企业级应用中常见的安全控制流程。
二、Shiro项目实战
1、创建项目,加入依赖
https://start.spring.io/简单创建项目。
<!-- 包含starter-web依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- thymeleaf依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- shiro标签使用-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、添加application配置
#开启shiro配置
shiro.enabled=true
#开启shiroWeb配置
shiro.web.enabled=true
#配置登录地址,默认“/login.jsp”
shiro.loginUrl=/login
#配置登录成功地址,默认“/”
shiro.successUrl=/index
#配合未获授权跳转地址
shiro.unauthorizedUrl=/unauthorized
#表示是否允许通过url参数实现会话跟踪,如果网站支持cookie,可以关闭该选项,默认true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
#表示是否允许通过cookie实现会话跟踪,默认true
shiro.sessionManager.sessionIdCookieEnabled=true
3、添加Shiro的配置类
因没有数据库可以连接,获取用户,配置了两个bean,分别是创建用户以及请求的过滤规则;
package com.yangxf.demoShiro.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.TextConfigurationRealm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 〈Shiro使用的简单配置〉
*
* @author linwd
* @create 2021/4/1
* @since 1.0.0
*/
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
TextConfigurationRealm textConfigurationRealm = new TextConfigurationRealm();
/**
* 简单范例,没有从数据库读取用户信息
* 直接配置了两个用户,admin/123456和yangxf/123456
* admin有读写权限,yangxf有读的权限
*/
textConfigurationRealm.setUserDefinitions("admin=123456,admin\n yangxf=123456,user");
textConfigurationRealm.setRoleDefinitions("admin=read,write\n yangxf=read");
return textConfigurationRealm;
}
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
/**
* 配置基本过滤规则
* /login以及/doLogin可以匿名访问
* /logout是注销登录请求
* /index需要认证后访问
*/
defaultShiroFilterChainDefinition.addPathDefinition("/login", "anon");
defaultShiroFilterChainDefinition.addPathDefinition("/doLogin", "anon");
defaultShiroFilterChainDefinition.addPathDefinition("/logout", "logout");
defaultShiroFilterChainDefinition.addPathDefinition("/index", "authc");
return defaultShiroFilterChainDefinition;
}
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
4、配置登录接口以及页面访问接口
package com.yangxf.demoShiro.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 〈配置登录接口以及页面访问接口〉
*
* @author linwd
* @create 2021/4/1
* @since 1.0.0
*/
@RestController
public class UserController {
/**
* 登录接口
* @param username
* @param password
* @param model
* @return
*/
@GetMapping("/doLogin")
public String doLogin(String username, String password, Model model){
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
Subject subject= SecurityUtils.getSubject();
try{
subject.login(token);
}catch (AuthenticationException e){
model.addAttribute("error","用户或密码输入错误");
return "login";
}
return "redirect:/index";
}
@RequiresRoles("admin")
@GetMapping("/admin")
public String admin(){
return "admin";
}
@RequiresRoles(value = {"admin","user"},logical = Logical.OR)
@GetMapping("/user")
public String user(){
return "user";
}
}
5、配置WebMvc
/**
* 〈web配置〉
*
* @author linwd
* @create 2021/4/1
* @since 1.0.0
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 不需要访问权限的接口配置
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/error").setViewName("error");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/unauthorized").setViewName("unauthorized");
}
}
6、配置全局异常处理
这里主要处理授权异常的情况;
package com.yangxf.demoShiro.exception;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* 〈一句话功能简述〉<br>
* 〈统一异常处理器〉
*
* @author linwd
* @create 2021/4/1
* @since 1.0.0
*/
@ControllerAdvice
public class ExceptionController {
/**
* 处理授权异常
*
* @param e
* @return
*/
@ExceptionHandler(AuthorizationException.class)
public ModelAndView error(AuthorizationException e) {
ModelAndView mv = new ModelAndView("unauthorized");
mv.addObject("error", e.getMessage());
return mv;
}
}
7、html页面添加
- login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/doLogin",method="POST">
<input type="text" name="usename"><br>
<input type="password" name="password"><br>
<div th:text="${error}"></div>
<input type="sbumit" value="登录">
</form>
</body>
</html>
- index.html
<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>Hello<shiro:principal/></h3>
<h3></h3>
<h3><a href="/logout">注销登录</a> </h3>
<h3><a shiro:hasRole="admin" href="/admin">管理员登录页面</a> </h3>
<h3><a shiro:hasRole="admin,user" href="/user">普通登录页面</a> </h3>
</body>
</html>
- user.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>普通用户界面</h1>
</body>
</html>
- admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>管理员界面</h1>
</body>
</html>
- unauthorized.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>未授权,非法访问</h3>
<div th:text="${error}"></div>
</body>
</html>
8、测试
验证结果
登录http://lcoalhost:8080/login
分别以admin以及yangxf账户登录,后台根据录入的用户密码判断是否是授权用户,认证成功后,看到界面上显示的是不一样的,与配置一致。
ok;ok;ok;