赞
踩
Subject:用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:Shiro连接数据的桥梁
1.引入shiro相关maven依赖
<!-- shiro与spring整合依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- thymeleaf对shiro的标签扩展 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2. 创建Realm身份验证器
创建类后 继承 AuthorizingRealm,重写doGetAuthorizationInfo(授权逻辑)和doGetAuthenticationInfo(认证逻辑)方法。
package cn.czl.shiro; import cn.czl.domain.User; import cn.czl.domain.UserPower; import cn.czl.service.PowerService; import cn.czl.service.UserService; import cn.czl.service.impl.PowerServiceImpl; import cn.czl.service.impl.UserServiceImpl; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; 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 java.util.List; /** * 自定义Realm * @author RedRush * */ public class UserRealm extends AuthorizingRealm { //注入业务 @Autowired private UserService userService = new UserServiceImpl(); @Autowired private PowerService powerService = new PowerServiceImpl(); /** * 执行授权逻辑 * */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); //对资源进行授权 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //获取当前用户的id Subject subject = SecurityUtils.getSubject(); User user = (User)subject.getPrincipal(); //到数据库查询当前用户的授权字符串 User dbUser = userService.findBasicById(user.getUid()); //添加资源的授权字符串(关联授权过滤器后面的字符串) // authorizationInfo.addStringPermission("user:add"); // authorizationInfo.addStringPermission(dbUser.getPerms()); //添加角色的授权字符串 authorizationInfo.addRole(dbUser.getRole()); //将权限列表批量导入 List <UserPower> userPowers= powerService.getUpower(dbUser.getPid()); for (UserPower userPower:userPowers){ System.out.println(userPower); authorizationInfo.addStringPermission(userPower.getPerm()); } // List<Perm> perms = permDao.getPermById(user.getUid()); // for (Perm perm : perms){ // authorizationInfo.addStringPermission(perm.getPermName()); // } return authorizationInfo; } /** * 执行认证逻辑 * */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //编写shiro判断逻辑,判断用户名和密码 //1.判断用户名 UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; System.out.println(token.getUsername()); User user = userService.findByName(token.getUsername()); if(user == null){ //用户名不存在 return null;//shiro底层会抛出UnknownAccountException } //2.判断密码("返回给login方法的数据(授权方法可获取)","数据库密码","realm名字") return new SimpleAuthenticationInfo(user, user.getUpwd(), ""); } }
3. 创建ShiroConfig(Shiro配置)
package cn.czl.shiro; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; 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 java.util.LinkedHashMap; import java.util.Map; /** * shiro的配置类 * @author RedRush * */ @Configuration public class ShiroConfig { /** * 创建ShiroFilterFactoryBean * 创建shiro过滤器工厂 * */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //1.设置安全管理器 shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //2.添加Shiro内置过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截 * 常用的过滤器: * anon:无需认证(登陆)即可访问 * authc:必须认证才可以访问 * user:如果使用rememeberMe的功能可以直接访问 * perms:该资源必须得到资源权限才可以访问 * roles:该资源必须得到角色权限才可以访问 * */ Map<String, String> filterMap = new LinkedHashMap<String, String>(); //设置白名单(无需认证访问页面) filterMap.put("/testThymeleaf", "anon"); //放行login请求 filterMap.put("/login", "anon"); //授权过滤器 //注意:当前授权拦截后,shiro会自动跳转到未授权页面 filterMap.put("/manage", "roles[manage]"); filterMap.put("/add", "perms[user:add]"); filterMap.put("/update", "perms[user:update]"); //设置拦截url filterMap.put("/*", "authc"); // filterMap.put("/add", "authc"); // filterMap.put("/update", "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 * 身份验证器Realm(开发者自行编写设置认证、授权业务) * */ @Bean(name = "userRealm") public UserRealm gerRealm(){ return new UserRealm(); } /** * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用 * shiro方言(shiro权限判断标签) * */ @Bean public ShiroDialect getShiroDialect(){ System.out.println("创建ShiroDialect"); return new ShiroDialect(); } }
4. Controller层使用shiro进行认证
@RequestMapping("/login") public String login(String name, String password, Model model){ System.out.println("name" + name + ";password" + password); /** * 使用shiro编写认证操作 * */ //1.获取Subject Subject subject = SecurityUtils.getSubject(); //2.获取用户数据 UsernamePasswordToken token = new UsernamePasswordToken(name, password); //3.执行登陆方法 try { subject.login(token); //登陆成功 //执行"/testThymeleaf"请求,重定向,跳转到test.html return "redirect:/testThymeleaf"; }catch (UnknownAccountException e){ //e.printStackTrace(); //登陆失败:用户名不存在 model.addAttribute("msg", "用户名不存在"); return "login"; }catch (IncorrectCredentialsException e){ //登陆失败:密码错误 model.addAttribute("msg","密码错误"); return "login"; } }
5. 页面中使用Thymeleaf配合shiro进行模块权限控制
<div shiro:hasPermission="user:update">
<a href="update">用户更新</a>
</div>
<div shiro:hasRole="manager">管理员您好</div>
项目目录结构:
我的github源码,数据库表结构和数据也放进去了,欢迎学习交流。
有用的话,给个小星星吧。阿里嘎多https://github.com/Iron-Rush/springboot-shiro.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。