项目搭建
项目整体框架
核心部分讲解
1、 主要依赖
<dependencies> <!-- 导入数据源--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <!-- lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.3</version> </dependency> <!-- thymeleaf--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency> <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> </dependencies>
2、先自定义核心组件Realm(主要是用来认证和授权的)
public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; @Override //授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("开始授权"); final SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // info.addStringPermission("user:add"); //得到当前登入的对象 final Subject subject = SecurityUtils.getSubject(); //得到user对象 final User user = (User) subject.getPrincipal(); //设置当前用户权限 info.addStringPermission(user.getPerms()); info.addRole("admin"); return info; } @Override //认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("开始认证"); // String name="root"; // String password="123456"; final UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; final User user = userService.getUserByName(token.getUsername()); if(user==null){ return null; } //密码认证,shiro做 return new SimpleAuthenticationInfo(user,user.getPwd(),""); } }
3、配置Shiro
(这里配置的三个Bean在项目启动的时候就已经注入到Spring大容器中了)
@Configuration public class ShiroConfig { @Bean //第三步 ShiroFilterFactoryBean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ final ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(securityManager); //添加内置过滤器 /** * anon 无需认证即可访问 * authc 需要认证才可访问 * user 记住我 * perms 拥有对某个资源的权限才能访问 * roles 拥有某个角色权限才可以访问 */ Map<String, String> filterMap=new LinkedHashMap<>(); filterMap.put("/user/add","authc"); filterMap.put("/user/update","authc"); //授权 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/update","roles[admin]"); bean.setFilterChainDefinitionMap(filterMap); //设置登入的请求 bean.setLoginUrl("/toLogin"); //设置未授权请求 bean.setUnauthorizedUrl("/unauth"); return bean; } //第二步 DefaultWebSecurityManage @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getUserRealm") UserRealm realm){ final DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联realm securityManager.setRealm(realm); return securityManager; } //第一步 创建realm 对象 自定义类UserRealm @Bean public UserRealm getUserRealm(){ return new UserRealm(); } }
在这里Shiro主要配置了三个Bean:
1、首先需要提供一个Realm的实例。(前面一步已经做了)
2、需要配置一个DefaultWebSecutityManage,再DefaultWebSecutityManage配置Realm。
3、配置一个ShiroFilterFactoryBean,在ShiroFilterFactoryBean中配置路径拦截规则。
4、配置登录和测试接口。
filterMap中配置了路径拦截规则,注意要有序。
4、配置登入controller
(登入接口中有玄机)
@Controller public class MyController { @RequestMapping({"/","/index"}) public String toIndex(Model model){ model.addAttribute("msg","hello,shiro"); return "index"; } @RequestMapping("/user/add") public String add(){ return "user/add"; } @RequestMapping("/user/update") public String update(){ return "user/update"; } @RequestMapping("/toLogin") public String toLogin(){ return "login"; } @RequestMapping("/login") public String login(String username,String password,Model model){ //获取当前用户 final Subject subject = SecurityUtils.getSubject(); //封住用户的登入数据 final UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token);//执行登录方法,如果没有异常就ok return "index"; } catch (UnknownAccountException e) {//用户名不存在 model.addAttribute("msg","用户名不存在"); return "login"; }catch (IncorrectCredentialsException e){ model.addAttribute("msg","密码错误"); return "login"; } } @RequestMapping("/unauth") @ResponseBody public String Unauthorized(){ return "未授权页面"; } }
subject.login(token);//执行登录方法,如果没有异常就ok,这里登录会进入到shiro配置中认证那一块的代码
这里只展示出部分代码,具体源代码可以参考 https://gitee.com/liujun1681/shiro-test