Spring boot 2.0 结合 shiro 使用心得

shiro目前使用的人越来越多,这里讲的主要用来就是登录验证、权限验证。

Spring boot 2.0新建项目上篇已经说明了,这里直接添加依赖


   org.apache.shiro
   shiro-core
   1.2.2


   org.apache.shiro
   shiro-spring
   1.2.2

然后我们需要做两件事

1.配置shiro

@Configuration
public class ShiroConfigBean {
   /**
    * Shiro配置Bean,引入依赖之后共需要做两件事,第一是配置,第二是自定义的realm
    */


   @Bean
   public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) {
      System.out.println("ShiroConfiguration.shirFilter()");
      ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

      // 必须设置 SecurityManager
      shiroFilterFactoryBean.setSecurityManager(securityManager);
      // 拦截器.
      Map filterChainDefinitionMap = new LinkedHashMap();
      // 设置login URL
      shiroFilterFactoryBean.setLoginUrl("/login");
      // 登录成功后要跳转的链接
      shiroFilterFactoryBean.setSuccessUrl("/LoginSuccess.html");
      // 未授权的页面
      shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized.html");
      // 使静态资源 生效
      filterChainDefinitionMap.put("/static/**", "anon");
      // 设置登录的地址可以匿名访问,因为一开始没有用户验证
      filterChainDefinitionMap.put("/login.html", "anon");
      //异常类
      filterChainDefinitionMap.put("/Exception.class", "anon");
      //拦截信息
      filterChainDefinitionMap.put("/*.html", "authc");
      // 退出系统的过滤器
      filterChainDefinitionMap.put("/logout", "logout");
      // 现在资源的角色
      filterChainDefinitionMap.put("/admin.html", "roles[admin]");
      // filterChainDefinitionMap.put("/user.html", "roles[user]");
      // 最后
      filterChainDefinitionMap.put("/**", "authc");
      shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
      return shiroFilterFactoryBean;
   }

   /*
    * 由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
    * 所以我们需要修改下doGetAuthenticationInfo中的代码; 
    */
   @Bean
   public HashedCredentialsMatcher hashedCredentialsMatcher() {
      HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
      hashedCredentialsMatcher.setHashAlgorithmName("md5");// 散列算法:这里使用MD5算法;
      hashedCredentialsMatcher.setHashIterations(1024);// 散列的次数,比如散列两次,相当于md5(md5(""));
      return hashedCredentialsMatcher;
   }
//这里提供密码加密后的字符串可以放在数据库使用
   public static void main(String[] args) {
      String hashAlgorithmName = "MD5";
      String credentials = "123456";
      int hashIterations = 1024;
      Object obj = new SimpleHash(hashAlgorithmName, credentials, null, hashIterations);
      System.out.println(obj);
   }
   //将自己的验证方式加入容器,否则是不生效的
   @Bean
   public MyShiroRealm myShiroRealm() {
      MyShiroRealm myShiroRealm = new MyShiroRealm();
      myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());//根据上面的主方法得到加密后的密码放到数据库中
      return myShiroRealm;
   }
   //权限管理,配置主要是Realm的管理认证
   @Bean
   public DefaultWebSecurityManager securityManager() {
      DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
      // 注入自定义的realm;
      securityManager.setRealm(myShiroRealm());
      // 注入缓存管理器;
      securityManager.setCacheManager(ehCacheManager());

      return securityManager;
   }

   /*
    * 开启shiro aop注解支持 使用代理方式;所以需要开启代码支持;
    * 加入注解的使用,不加入这个注解不生效
    */
   @Bean
   public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
         DefaultWebSecurityManager securityManager) {
      AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
      authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
      return authorizationAttributeSourceAdvisor;
   }

  
   /**
    * shiro缓存管理器;
    * 需要注入对应的其它的实体类中-->安全管理器:securityManager可见securityManager是整个shiro的核心;
    * 这个根据需要自己配置
   
   @Bean
   public EhCacheManager ehCacheManager() {
      System.out.println("ShiroConfiguration.getEhCacheManager()");
      EhCacheManager cacheManager = new EhCacheManager();
      cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
      return cacheManager;
   }
   */
}

2.具体的验证方法

/**
 * realm实现类,用于实现具体的验证和授权方法
 *
 *
 */
public class MyShiroRealm extends AuthorizingRealm {
  
 
   @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
      //获取用户信息
      String name = authenticationToken.getPrincipal().toString();
      //开始模拟数据库查找到数据-自行新建user类,不多说了
      User user=new User();
      user.setId(1);
      user.setUsername("test");
      user.setPassword("fc1709d0a95a6be30bc5926fdb7f22f4");
      //模拟结束
       if (!name.equals(user.getUsername())) {//这里验证用户名
         //这里返回后会报出对应异常
         return null;
      } else {
         //这里验证authenticationToken和simpleAuthenticationInfo的信息,这里验证密码
         SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword(), getName());
         return simpleAuthenticationInfo;
      }
   }
       


   // 用于授权
   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

      //获取登录用户名
      String name= (String) principals.getPrimaryPrincipal();

      //开始模拟数据库查找到数据
      User user=new User();
      user.setId(1);
      user.setUsername("test");
      user.setPassword("fc1709d0a95a6be30bc5926fdb7f22f4");//123456加密后
           
      //开始模拟数据库中角色
      role r=new role();
      r.setUserId(1);
      r.setId(1);
      r.setRole("admin");
      //开始模拟数据库中权限
      permission p=new permission();
      p.setId(1);
      p.setLimit("a");
      p.setRoleId(1);
      //模拟结束

      //添加角色,后边用来限制访问
     SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
      simpleAuthorizationInfo.addRole(r.getRole());

      //添加权限,后边用来限制访问
      simpleAuthorizationInfo.addStringPermission(p.getLimit());
      return simpleAuthorizationInfo;
   }

}

这里shiro的简单配置基本结束,下面就是应用了

在控制层,哪个方法需要对应的权限了就添加注解就可以了,举个简单的例子

@RequestMapping("/showAdminHtml")
@RequiresRoles("admin")//需要admin角色
   @RequiresPermissions("a")//需要a的权限
public String adminHtml() {
   
   return "/admin";//登录此页面
}

符合角色权限要求即可跳转admin页面。

如有失误请留言

你可能感兴趣的:(物联网项目搭建过程体会心得)