Springboot:springboot整合Shiro(JdbcRealm 方式)
阿新 • • 發佈:2020-09-22
1、匯入依賴
<dependencies> <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.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <!-- mysql驅動 依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> <scope>runtime</scope> </dependency> <!--Druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency> </dependencies>
2、書寫配置檔案
spring: datasource: druid: username: root password: root driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true
3、配置過濾器
@Configuration public class ShiroConfig { @Bean public JdbcRealm getJdbcRealm(DataSource dataSource){ //JdbcRealm會自行從資料庫查詢使用者以及許可權資料(資料庫的表結構要符合JdbcRealm的規範) JdbcRealm jdbcRealm=new JdbcRealm(); jdbcRealm.setDataSource(dataSource); //JdbcRealm預設開啟認證功能,需要手動開啟授權功能 jdbcRealm.setPermissionsLookupEnabled(true); return jdbcRealm; } @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(JdbcRealm jdbcRealm){ DefaultWebSecurityManager defaultSecurityManager=new DefaultWebSecurityManager(); defaultSecurityManager.setRealm(jdbcRealm);//SecurityManager完成校驗需要realm return defaultSecurityManager; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager){ ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean(); //過濾器是shiro執行許可權的核心,進行認證和授權是需要SecurityManager的 filter.setSecurityManager(securityManager); //設定shiro的攔截規則 Map<String,String> filterMap=new HashMap<>(); //user:使用remberme的使用者可訪問 //perms:對應許可權可訪問 //role:對應的角色才能訪問 filterMap.put("/","anon");//anon表示不攔截(匿名使用者可訪問) filterMap.put("/login.html","anon"); filterMap.put("/regist.html","anon"); filterMap.put("/user/login","anon"); filterMap.put("/user/regist","anon"); filterMap.put("/static/**","anon"); filterMap.put("/**","authc");//authc表示認證使用者可訪問 filter.setFilterChainDefinitionMap(filterMap); filter.setLoginUrl("/login.html"); //設定未授權訪問的頁面 filter.setUnauthorizedUrl("/login.html"); return filter; } }
使用資料庫中的使用者資料的時候,這裡的realm是不同的,下面的安全管理器和過濾器是一樣的
4、頁面跳轉的controller
@Controller public class PageController { @RequestMapping("/login.html") public String login(){ return "login"; } @RequestMapping("/") public String login1(){ return "login"; } @RequestMapping("/index.html") public String index(){ return "index"; } }
5、認證
在service層書寫方法,根據使用者輸入的使用者名稱和密碼完成使用者身份的校驗:
@Service public class UserService { public void checkLogin(String username,String password) throws Exception{ Subject subject= SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(username,password); subject.login(token); } }
書寫controller呼叫service層的校驗方法,根據校驗的結果跳轉到不同的頁面並給出相應的提示資訊:
@Controller @RequestMapping("user") public class UserController { @Autowired private UserService userService; @RequestMapping("login") public String login(String username,String password){ try{ userService.checkLogin(username,password); System.out.println("成功"); System.out.println(username+password); return "index"; }catch (Exception e){ e.printStackTrace(); System.out.println("失敗"); System.out.println(username+password); return "login"; } } }
登入頁面:
<body> <form action="/user/login"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="提交"> </form> </body>
index頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h3>index</h3> </body> </html>
6、資料庫
建立一個名稱為users的表,裡面有username和password欄位:
這裡要注意表的名稱,必須為users,否則會給出出錯資訊:
必須為users的原因是我們並沒有書寫操作資料庫的程式碼,預設找的是users表中的資料,因此,名稱數固定的
7、 測試
(1)輸入資料庫中存在的使用者資訊
(2)輸入資料庫中不存在的使用者資訊
跳轉到的是登入頁面,未能跳轉index頁面,登入失敗