1、创建项目的环境,添加maven的依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2、创建一个 AuthorizingRealm 的子类,用这个类进行两个操作,一个用来授权,一个用来认证
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("调用授权:=》doGetAuthorizationInfo");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("调用认证:=》doGetAuthorizationInfo");
if (StringUtils.isEmpty(token.getPrincipal())) {
return null;
}
//获取用户信息
String name = token.getPrincipal().toString();
String username = "root";
String password = "123456";
if (!username.equals(name)) {
//这里返回后会报出对应异常
return null;
} else {
//这里验证authenticationToken和simpleAuthenticationInfo的信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, password, getName());
return simpleAuthenticationInfo;
}
}
}
3、创建Shiro的核心配置类
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm (){
return new UserRealm();
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean (@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/**","authc");//需要认证之后才能访问的请求
bean.setFilterChainDefinitionMap(filterMap);
//如果没有认证,跳到登入页面
bean.setLoginUrl("/toLogin");
bean.setSuccessUrl("/index");
return bean;
}
}
4、创建html页面进行简单的测试
<!-- 首页-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<div th:text="${msg}"></div>
<a th:href="@{/user/add}">add</a> | <a th:href="@{user/update}">update</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>add</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>update</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>请登入</h1>
<p th:text="${msg}" style="color: red"></p>
<form action="/login">
<p>用户名: <input type="text" name="username"/></p>
<p>密码:<input type="text" name="password"/></p>
<p><input type="submit"/></p>
</form>
</body>
</html>
5、创建Controller进行页面跳转测试
@Controller
public class IndexController {
@RequestMapping({"/","/index"})
public String toIndex(Model model) {
model.addAttribute("msg","Hello,Shiro");
return "index";
}
@RequestMapping(value = "/user/add")
public String add () {
return "user/add";
}
@RequestMapping(value = "/user/update")
public String update () {
return "user/update";
}
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
@RequestMapping(value = "/login")
public String login (String username, String password,Model model) {
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
return "请输入用户名和密码!";
}
//用户认证信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
try {
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
// subject.checkRole("admin");
// subject.checkPermissions("query", "add");
return "index";
} catch (UnknownAccountException e) {
model.addAttribute("msg","用户名不存在");
return "login";
} catch (AuthenticationException e) {
model.addAttribute("msg","账号或密码错误");
return "login";
} catch (AuthorizationException e) {
model.addAttribute("msg","没有权限");
return "login";
}
}
}
6、创建统一的异常处理
@ControllerAdvice
@Slf4j
public class MyExceptionHandler {
@ExceptionHandler
@ResponseBody
public String ErrorHandler(AuthorizationException e) {
log.error("没有通过权限验证!", e);
return "没有通过权限验证!";
}
}