Shiro

Shiro的作用

image-20201102194608502.png

  • Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份。
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情。
  • Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是Web环境,Shiro有它自己的session。
  • Cryptography:加密。保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
  • Web Support:Web支持。
  • Caching:缓存。
  • Concurrency:Shiro支持多线程应用的并发验证,即在一个线程中开启另一个线程,能把权限自动传播过去。
  • Testing:提供测试支持。
  • Run As:允许一个用户假装为另一个用户(前提是被允许)的身份进行访问。
  • Remember Me:记住我。这个是非常常见的功能,即一次登录后,下次就不用登录了,基于cookie。

Shiro的内置过滤器

  1. /*
  2. anon:无需认证,即可访问
  3. authc:必须认证才可访问
  4. user:必须拥有 记住我 才能用
  5. perms:拥有对某个资源的权限才能访问
  6. role:拥有某个角色权限才能访问
  7. */
过滤级别 作用
anon 无需认证即可访问
authc 必须认证才可访问
user 必须拥有”记住我”才能用
perms 拥有对某个资源的权限才能访问
role 拥有某个角色权限才能访问

shiro相关方法

spring security也有

  1. Subject currentUser = SecurityUtils.getSubject();
  2. Session session = currentUser.getSession();
  3. currentUser.isAuthenticated();
  4. currentUser.getPrincipal();
  5. currentUser.hasRole("schwartz");
  6. currentUser.isPermitted("lightsaber:wield");
  7. currentUser.logout();

Shiro配置步骤

1、导入依赖

  1. <!--shiro整合spring-->
  2. <dependency>
  3. <groupId>org.apache.shiro</groupId>
  4. <artifactId>shiro-spring</artifactId>
  5. <version>1.7.0</version>
  6. </dependency>
  7. <!--Shiro-->
  8. <dependency>
  9. <groupId>org.apache.shiro</groupId>
  10. <artifactId>shiro-core</artifactId>
  11. <version>1.6.0</version>
  12. </dependency>

2、自定义一个Realm类,重写授权与认证方法

  1. /**
  2. * 自定义的Realm
  3. */
  4. public class UserRealm extends AuthorizingRealm {
  5. @Resource
  6. AdminMapper adminMapper;
  7. /**
  8. * 授权
  9. * @param principalCollection
  10. * @return
  11. */
  12. @Override
  13. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  14. System.out.println("执行了=>授权doGetAuthorizationInfo");
  15. return null;
  16. }
  17. /**
  18. * 认证
  19. * @param authenticationToken
  20. * @return
  21. * @throws AuthenticationException
  22. */
  23. @Override
  24. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
  25. System.out.println("执行了=>认证doGetAuthenticationInfo");
  26. UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken; //取得账户密码令牌
  27. Admin admin = adminMapper.queryAdmin(userToken.getUsername());
  28. if (admin == null) {
  29. return null; //抛出异常UnknownAccountException
  30. }
  31. //密码认证
  32. return new SimpleAuthenticationInfo("", admin.getPassword(), "");
  33. }
  34. }

3、写一个Shiro的配置类

  1. @Configuration
  2. public class ShiroConfig {
  3. @Bean(value = "userRealm")
  4. public UserRealm getUserRealm() {
  5. return new UserRealm();
  6. }
  7. @Bean(value = "securityManager")
  8. public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
  9. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  10. securityManager.setRealm(userRealm); //装配自定义的userRealm
  11. return securityManager;
  12. }
  13. @Bean
  14. public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
  15. ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
  16. bean.setSecurityManager(securityManager); //安全管理器
  17. //添加shiro的内置过滤器
  18. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
  19. filterChainDefinitionMap.put("/blog.html", "authc");
  20. filterChainDefinitionMap.put("/list.html", "authc");
  21. bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  22. bean.setLoginUrl("/admin/toLogin"); //被拦截后跳转到登录页面
  23. return bean;
  24. }
  25. }

4、controller层

  1. @RequestMapping("/login")
  2. public String login(@RequestParam("name") String name, @RequestParam("password") String password,
  3. Model model, HttpSession session) {
  4. //获取用户名和密码
  5. Subject subject = SecurityUtils.getSubject();
  6. UsernamePasswordToken token = new UsernamePasswordToken(name, password);
  7. try {
  8. subject.login(token); //判断用户名和密码是否正确,不正确则抛出异常
  9. Admin admin = adminMapper.queryAdmin(name);
  10. session.setAttribute("login_admin", admin);
  11. return "blog";
  12. }catch (UnknownAccountException e) { //用户不存在
  13. model.addAttribute("msg", "用户名错误");
  14. return "login";
  15. }catch (IncorrectCredentialsException e) { //密码错误
  16. model.addAttribute("msg", "密码错误");
  17. return "login";
  18. }
  19. }