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页面,登录失败