简介:
Apache Shiro 是一一个开源的轻量级的Java安全框架,它提供身份验证、授权、密码管理以及会话管理等功能。
相对于Spring Security, Shiro框架更加直观、易用,同时也能提供健壮的安全性。在传统的SSM框架中,手动整合Shiro的配置步骤还是比较多的,针对Spring Boot, Shiro 官方提供了shiro-spring-boot-web-starter 用来简化Shiro 在Spring Boot 中的配置。
pom.xml
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> //已经依赖spring-boot-web-starter <version>1.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
application.properties
#开启shiro
shiro.enabled=true #开启shiro web
shiro.web.enabled=true #登陆地址,默认/login.jsp
shiro.loginUrl=/login #登陆成功地址
shiro.successUrl=/index #未获授权跳转地址
shiro.unauthorizedUrl=/unauthorized #是否允许通过url进行会话跟踪,默认true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true #是否允许通过Cookie实现会话跟踪
shiro.sessionManager.sessionIdCookieEnabled=true
配置shiro
@Configuration public class ShiroConfig { @Bean public Realm realm() {//添加用户 TextConfigurationRealm realm = new TextConfigurationRealm(); realm.setUserDefinitions("sang=123,user admin=123,admin"); //添加用户名+密码+角色 realm.setRoleDefinitions("admin=read,write user=read"); //添加权限 return realm; }
@Bean #添加过滤规则
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); chainDefinition.addPathDefinition("/login", "anon"); //可以匿名访问 chainDefinition.addPathDefinition("/doLogin", "anon"); //同上 chainDefinition.addPathDefinition("/logout", "logout"); //注销登陆 chainDefinition.addPathDefinition("/**", "authc"); //其余请求都需要认证后擦可以访问 return chainDefinition; } @Bean public ShiroDialect shiroDialect() { //可以在Thymeleaf中使用shiro标签 return new ShiroDialect(); } }
controller:
@Controller public class UserController {
@GetMapping("/hello")
public String hello() {
return "hello shiro!";
}
@PostMapping("/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") //admin角色 @GetMapping("/admin") public String admin() { return "admin"; }
@RequiresRoles(value = {"admin","user"},logical = Logical.OR) //admin或者user任意一个都可以 @GetMapping("/user") public String user() { return "user"; } }
对于不需要角色就可以访问的页面
@Configuration public class WebMvcConfig implements WebMvcConfigurer{ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("login"); registry.addViewController("/index").setViewName("index"); registry.addViewController("/unauthorized").setViewName("unauthorized"); } }
全局异常处理:
@ControllerAdvice public class ExceptionController { @ExceptionHandler(AuthorizationException.class) public ModelAndView error(AuthorizationException e) { ModelAndView mv = new ModelAndView("unauthorized"); mv.addObject("error", e.getMessage()); return mv; } }
新建5个页面:
admin.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>管理员页面</h1> </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><a href="/logout">注销登录</a></h3> <h3><a shiro:hasRole="admin" href="/admin">管理员页面</a></h3> <h3><a shiro:hasAnyRoles="admin,user" href="/user">普通用户页面</a></h3> </body> </html>
login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <form action="/doLogin" method="post"> <input type="text" name="username"><br> <input type="password" name="password"><br> <div th:text="${error}"></div> <input type="submit" value="登录"> </form> </div> </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> <div> <h3>未获授权,非法访问</h3> <h3 th:text="${error}"></h3> </div> </body> </html>
user.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>普通用户页面</h1> </body> </html>
访问http://localhost:8080/login
由于上面的shiro配置,可以匿名访问
输入我们在shiro配置的2用户
sang/123
admin/123
不同角色,权限不一样,页面也不一样