Shiro ??
Apache Shiro? ??, ??, ???? ??, ?? ?? ? ?? ??? ???? ?? ?? ?? Java ?? ????????. Spring Security? ?? Shiro ?????? ? ????? ???? ??? ??? ??? ?????.
?? SSM ??????? Shiro? ???? ???? ? ??? ?? ?? ??? ????. Spring Boot? ?? Shiro? Spring Boot?? Shiro ??? ????? ?? ????? shiro-spring-boot-web-starter? ?????.
Shiro ??
1. ???? ???
?? ?? Spring Boot ? ????? ??? Shiro ??? ? ??? ??? ???? ?????.
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<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>
spring-boot-starter-web ???, shiro-spring? ??? ??? ????. -boot -web-starter? ?? spring-boot-starter-web? ?????. ??? Thymeleaf?? shiro ??? ???? ?? Thymeleaf ???? ?????. thymeleaf-extras-shiro ???? ?????.
2. Shiro ?? ??
application.properties?? Shiro? ?? ??? ?????
# Shiro ??? ??????. ???? true
shiro.enabled=true
# Shiro ? ??? ??????. ???? true
shiro .web .enabled=true
# ??? ??? ?????. ???? /login.jsp
shiro.loginUrl=/login
# ???? ???? ?? ??? ?????. ???? /
shiro.successUrl=/index
# Unauthorized ?? ?? ??
shiro.unauthorizedUrl=/unauthorized
# URL ????? ?? ?? ?? ?? ??. ????? ??? ???? ?? ? ??? ? ? ????. ???? true???. ??? ?? ?? ??? ????? ???? Set true
shiro.sessionManager.sessionIdCookieEnabled=true
?? ?? Java ??? Shiro? ???? ?? ???? ? ?? Bean? ?????.
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
TextConfigurationRealm realm = new TextConfigurationRealm();
realm.setUserDefinitions("sang=123,user\n admin=123,admin");
realm.setRoleDefinitions("admin=read,write\n 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() {
return new ShiroDialect();
}
}
?? ??:
??? ? ?? ??? ????. ??? Realm?? ?? ??? ShiroFilterChainDefinition???. ShiroDialect? ?? Thymeleaf?? Shiro ?? ??? ???? ?? ????. Thymeleaf?? Shiro ??? ???? ??? ShiroDialect? ??? ??? ????. Realm? ??? ?? Realm??? Shiro? ???? Realm? ? ????. ???? ?? ???? ?????? ??? ???? ?? ??? ?? user ? admin ??? ???? ? ?? ???(sang/123 ? admin/123)? ?? ?????. ShiroFilterChainDefinition Bean? ?? ??? ??? "/login" ? "/doLogin"?? ???? ???? ???? ? ?? "/logout"? ???? ???? ?? ??? ????? ?? ??? ?????-
Then ??? ????? ? ??? ??? ????? ??
@Controller
public class UserController {
@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")
@GetMapping("/admin")
public String admin() {
return "admin";
}
@RequiresRoles(value = {"admin", "user"}, logical = Logical.OR)
@GetMapping("/user")
public String user() {
return "user";
}
}
?? ??:
doLogin ????? ?? UsernamePasswordToken ????? ??? ?? Subject ??? ???? ???? ??? ???? ???? ??? ??? ?????. ??? ?? ?? ???? ??? ???? ???? ????? ????, ???? ???? "/index"? ???????. ?? , ? ????? "/admin" ? "/admin"? "/user"? ?????. "/admin" ?????? ?? "/user" ?????? ?????? ??? ??? ??? ???. ?????? ??? ???? ??? ??? ??? ???. ?? ??? ?? ???? ?????? WebMvc
@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;
}
}
???? ???? ?? ???? ????? ???? ?? ??? ???? ?? ???? ?????.
??? ???? ????? resources/templates ????? ???? HTML ??? 5?? ?????.
(1) 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>
<h4>Hello, <shiro:principal/></h4>
<h4><a href="/logout" rel="external nofollow" >注銷登錄</a></h4>
<h4><a shiro:hasRole="admin" href="/admin" rel="external nofollow" >管理員頁面</a></h4>
<h4><a shiro:hasAnyRoles="admin,user" href="/user" rel="external nofollow" >普通用戶頁面</a></h4>
</body>
</html>
(2) 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>
(3) user.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>普通用戶頁面</h2>
</body>
</html>
(4) admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>管理員頁面</h2>
</body>
</html>
(5) ??.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<h4>未獲授權(quán),非法訪問</h4>
<h4 th:text="${error}"></h4>
</div>
</body>
</html>
3.
????? ???? ??? ???? ???? sang/123
? ???? ??????. ??: sang ?????? ??? ??? ???? ??? ?? ? ????? ??? ???? ?? ?????? ????. .
?? ?? admin/123? ???? ??????.
???? sang? ???? ???? ? http://localhost:8080/admin? ???? ???? ?? ???? ?????
? ??? SpringBoot ?? ??? Shiro ?????? ???? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!