【DAY12】shiro实现权限的认证和授权
今天主要是通过使用shiro,在不同身份的用户登录时,实现不同的权限,可以完成不同的功能。
数据库设计
t_role表 t_role_permissions表 t_user_roles表 t_user中有一列存储用户身份
实现步骤
新建realm包,新建NewsRealm类实现授权和认证
public class NewsRealm extends AuthorizingRealm { public void setName(String name){ setName("newsRealm"); } @Autowired private IUserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { User user = (User) principalCollection.getPrimaryPrincipal(); Set<Role> roles = user.getRoles(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); for(Role r: roles){ info.addRole(r.getName()); for(Permission p:r.getPermissions()){ info.addStringPermission(p.getCode()); } } return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; String username = token.getUsername(); String password = new String(token.getPassword()); User user = userService.checkUser(username, password); if(user != null){ return new SimpleAuthenticationInfo(user, password, this.getName()); }else{ return null; } } }
新建一个ShiroConfiguration类,实现shiro配置功能
@Configuration public class ShiroConfiguration { @Bean public NewsRealm getRealm(){ return new NewsRealm(); } @Bean public SecurityManager securityManager(NewsRealm newsRealm){ return new DefaultWebSecurityManager(newsRealm); } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/admin"); shiroFilterFactoryBean.setUnauthorizedUrl("/unauthor"); Map<String, String> filterMap = new LinkedHashMap<>(); //anon 都不拦截 //authc 都拦截 filterMap.put("/admin/login", "anon"); filterMap.put("/admin/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } @Bean public AuthorizationAttributeSourceAdvisor advisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }
登录方法也进行了重写
@PostMapping("login") public String login(String username, String password, HttpSession session, RedirectAttributes redirectAttributes) { try{ UsernamePasswordToken token = new UsernamePasswordToken(username, password); Subject subject = SecurityUtils.getSubject(); subject.login(token); User user = (User) subject.getPrincipal(); session.setAttribute("user", user); return "admin/index"; }catch (Exception e){ redirectAttributes.addFlashAttribute("message","用户名和密码错误哦"); return "redirect:/admin"; } }
使用过程中,使用@RequiresPermissions或者@RequiresRoles来进行授权。我测试时,在ITypeService接口实现类中使用的是下方代码
@Override @RequiresPermissions(value = "user-delete") public void deleteById(Long id) { typeDao.deleteById(id); }
@RequiresPermissions(value = “user-delete”),这样只有拥有删除权限的管理员可以删除,没有权限的用户就不会执行。
上一篇:
通过多线程提高代码的执行效率例子