【基础】springboot+shiro
一、简介
- 最基础springboot+shiro整合,个人初接触学习记录使用。视频地址
二、项目结构
三、Java代码
1.pom.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.dx</groupId> <artifactId>spboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spboot</name> <description>Demo project for Spring Boot</description> <!--修改参数 --> <properties> <java.version>1.8</java.version> <shiro.version>1.4.0</shiro.version> </properties> <!--导入依赖,web启动器,导入web支持 --> <dependencies> <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.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.application.yml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
spring:
profiles:
active: dev
3.application-dev.yml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
server:
port: 8081
money: 0.15
content: 你在说什么批话,一共${money}元
4.application-prod.yml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
server:
port: 8081
money: 15
content: 你在说什么批话,一共${money}元
5.ShiroConfig.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.dx.shiro; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** * @Date: 2019/5/17 15:08 * @Author: dingxiao * @Description: */ @Configuration public class ShiroConfig { /** * 创建shiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager()); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); // 未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); /** * 添加shiro内置过滤器,可以实现权限相关的拦截器 * 常用的过滤器: * anon:无需认证(登陆)可以访问 * authc:必须认证才可以访问 * user:如果使用rememberMe的功能可以直接访问 * perms:该资源必须得到资源权限才可以访问 * role:该资源必须得到角色权限才可以访问 */ Map map = new LinkedHashMap<>(); map.put("/login","anon"); map.put("/toLogin","anon"); map.put("/**","authc"); // map.put("/update","anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); return shiroFilterFactoryBean; } /** * 创建DefaultWebSecurityManager */ @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(){ DefaultWebSecurityManager webSecurityManager= new DefaultWebSecurityManager(); webSecurityManager.setRealm(getRealm()); return webSecurityManager; } /** * 创建realm */ @Bean public UserRealm getRealm(){ UserRealm userRealm = new UserRealm(); return userRealm; } }
6.UserRealm.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.dx.shiro; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; /** * @Date: 2019/5/17 15:12 * @Author: dingxiao * @Description: 自定义realm类 */ public class UserRealm extends AuthorizingRealm { /** * 执行授权逻辑 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); return null; } /** * 执行认证逻辑 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("执行认证逻辑"); String name ="admin"; String password="1234qwer"; //编写shiro判断逻辑,判断用户名和密码 UsernamePasswordToken token = (UsernamePasswordToken)arg0; if(!name.equals(token.getUsername())){ return null; //用户名不存在,shiro底层会抛出UnKnowAccountException }//判断密码 return new SimpleAuthenticationInfo("",password,"");//shiro会自动判断 } }
7.IndexController.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.dx.spboot; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * @Date: 2019/5/17 15:54 * @Author: dingxiao * @Description: 跳转界面controller */ @Controller public class IndexController { @RequestMapping(value = "add") public ModelAndView add(){ ModelAndView modelAndView = new ModelAndView("user/add"); modelAndView.addObject("agename","难受"); return modelAndView; } @RequestMapping(value = "update") public ModelAndView update(){ ModelAndView modelAndView = new ModelAndView("user/update"); return modelAndView; } @RequestMapping(value = "login") public ModelAndView login(){ ModelAndView modelAndView = new ModelAndView("login"); return modelAndView; } }
8.HelloController.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.dx.spboot; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; /** * @Date: 2019/5/13 10:11 * @Author: dingxiao * @Description: */ @Controller public class HelloController { @Value("${money}") private String money ; @Value("${content}") private String content; @GetMapping(value = "/hello") public String say(){ return "index"; } /** * 测试thymeleaf是否可用 */ @RequestMapping(value = "testThymeleaf") public String testThymeleaf(Model model){ model.addAttribute("name","诺技师"); return "test"; } //登录逻辑处理 @RequestMapping(value = "toLogin") public String toLogin(String name,String password,Model model){ //使用shiro编写认证操作 //1.获取subject Subject subject = SecurityUtils.getSubject(); //2.封装用户数据 UsernamePasswordToken token = new UsernamePasswordToken(name,password); //3.执行登陆方法 try {//没有异常则登陆成功 subject.login(token); return "index"; } catch (UnknownAccountException e) { //用户名不存在异常 model.addAttribute("msg","账号不存在"); return "login"; }catch (IncorrectCredentialsException e){ //密码错误异常 model.addAttribute("msg","密码错误"); return "login"; } } }
9.login.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <h1 >用户登录</h1> <h3 th:text="${msg}" style="color: red"></h3> <form action="/toLogin" method="post"> 账号:<input type="text" name="name" id="name"><br> 密码:<input type="password" name="password" id="password"><hr/> <input type="submit" value="登陆"> </form> </body> </html>
10.index.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1 >大家好才是真的好</h1> <a href="add">添加用户</a> <a href="update">修改用户信息</a> </body> </html>
11.test.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html > <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试thymeleaf</title> </head> <body> <h3 th:text="${name}"></h3> </body> </html>
12.add.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE > <html lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>用户添加界面</title> </head> <body> <h1>用户添加界面</h1> <td th:text="${agename}"></td> </body> </html>
13.update.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户更新界面</title> </head> <body> <h1>用户更新界面</h1> </body> </html>
万般皆是命,唯有我不灵。