pom.xml配置
<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> <!-- 继承Spring Boot的默认父工程 --> <!-- Spring Boot 父工程 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <groupId>com.itheima</groupId> <artifactId>springboot-shiro</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 导入依赖 --> <dependencies> <!-- 导入web支持:SpringMVC开发支持,Servlet相关的程序 --> <!-- web支持,SpringMVC, Servlet支持等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 导入thymeleaf依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- shiro与spring整合依赖 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!-- 导入mybatis相关的依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- SpringBoot的Mybatis启动器 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- thymel对shiro的扩展坐标 --> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency> </dependencies> <!-- 修改参数 --> <properties> <!-- 修改JDK的编译版本为1.8 --> <java.version>1.8</java.version> <!-- 修改thymeleaf的版本 --> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> </properties> </project> |
ShiroConfig
package com.itheima.shiro; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; /** * Shiro的配置类 * @author lenovo * */ @Configuration public class ShiroConfig { /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //添加Shiro内置过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截器 * 常用的过滤器: * anon: 无需认证(登录)可以访问 * authc: 必须认证才可以访问 * user: 如果使用rememberMe的功能可以直接访问 * perms: 该资源必须得到资源权限才可以访问 * role: 该资源必须得到角色权限才可以访问 */ Map<String,String> filterMap = new LinkedHashMap<String,String>(); /*filterMap.put("/add", "authc"); filterMap.put("/update", "authc");*/ filterMap.put("/testThymeleaf", "anon"); //放行login.html页面 filterMap.put("/login", "anon"); //授权过滤器 //注意:当前授权拦截后,shiro会自动跳转到未授权页面 filterMap.put("/add", "perms[user:add]"); filterMap.put("/update", "perms[user:update]"); filterMap.put("/*", "authc"); //修改调整的登录页面 shiroFilterFactoryBean.setLoginUrl("/toLogin"); //设置未授权提示页面 shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /** * 创建DefaultWebSecurityManager */ @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联realm securityManager.setRealm(userRealm); return securityManager; } /** * 创建Realm */ @Bean(name="userRealm") public UserRealm getRealm(){ return new UserRealm(); } /** * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用 */ @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } } |
UserRealm
package com.itheima.shiro; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import com.itheima.domain.User; import com.itheima.service.UserService; /** * 自定义Realm * @author lenovo * */ public class UserRealm extends AuthorizingRealm{ /** * 执行授权逻辑 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { System.out.println("执行授权逻辑"); //给资源进行授权 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //添加资源的授权字符串 //info.addStringPermission("user:add"); //到数据库查询当前登录用户的授权字符串 //获取当前登录用户 Subject subject = SecurityUtils.getSubject(); User user = (User)subject.getPrincipal(); User dbUser = userSerivce.findById(user.getId()); info.addStringPermission(dbUser.getPerms()); return info; } @Autowired private UserService userSerivce; /** * 执行认证逻辑 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("执行认证逻辑"); //编写shiro判断逻辑,判断用户名和密码 //1.判断用户名 UsernamePasswordToken token = (UsernamePasswordToken)arg0; User user = userSerivce.findByName(token.getUsername()); if(user==null){ //用户名不存在 return null;//shiro底层会抛出UnKnowAccountException } //2.判断密码 return new SimpleAuthenticationInfo(user,user.getPassword(),""); } } |
UserController
package com.itheima.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; 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.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.itheima.service.UserService; @Controller public class UserController { /** * 测试方法 */ @RequestMapping("/hello") @ResponseBody public String hello(){ System.out.println("UserController.hello()"); return "ok"; } @RequestMapping("/add") public String add(){ return "/user/add"; } @RequestMapping("/update") public String update(){ return "/user/update"; } @RequestMapping("/toLogin") public String toLogin(){ return "/login"; } @RequestMapping("/noAuth") public String noAuth(){ return "/noAuth"; } /** * 测试thymeleaf */ @RequestMapping("/testThymeleaf") public String testThymeleaf(Model model){ //把数据存入model model.addAttribute("name", "黑马程序员"); //返回test.html return "test"; } /** * 登录逻辑处理 */ @RequestMapping("/login") public String login(String name,String password,Model model){ System.out.println("name="+name); /** * 使用Shiro编写认证操作 */ //1.获取Subject Subject subject = SecurityUtils.getSubject(); //2.封装用户数据 UsernamePasswordToken token = new UsernamePasswordToken(name,password); //3.执行登录方法 try { subject.login(token); //登录成功 //跳转到test.html return "redirect:/testThymeleaf"; } catch (UnknownAccountException e) { //e.printStackTrace(); //登录失败:用户名不存在 model.addAttribute("msg", "用户名不存在"); return "login"; }catch (IncorrectCredentialsException e) { //e.printStackTrace(); //登录失败:密码错误 model.addAttribute("msg", "密码错误"); return "login"; } } } |