常见过滤器ShiroFilter

注意:shiro提供了多个默认的过滤器,我们可以用这些过滤器来配置控制指定的URL的权限。

配置缩写 对应的过滤器 动能
anno AnonymousFilter 指定urt可以匿名访问,无序认证就可以访问
authc FormAuthenticationFilter 认证后才能访问
authcBasic BasicHttpAuthenticationFiter 指定URL需要basic登录
logout LogoutFiter 登出过滤器,配置URL就可以实现退出功能,非常方便
noSessionCreation NoSessionCreationFilter 禁止创建会话
perms PermissionsAuthorizationFilter 需要指定权限才能访问
port PortFilter 需要指定端口才能访问
rest HttpMethodPermissionFilter 将http请求方式转化为相应的动词来构成一个权限字符串,一般很少用到
roles RolesAuthorizationFilter 需要指定角色才能访问
ssl SslFilter 需要https请求才能访问
user UserFilter 需要已登录或实现”记住我“的用户才能访问

加入依赖

<!--shiro整合thymeleaf-->
   <dependency>
       <groupId>com.github.theborakompanioni</groupId>
       <artifactId>thymeleaf-extras-shiro</artifactId>
       <version>2.0.0</version>
   </dependency>
   <!--shiro-->
   <dependency>
       <groupId>org.apache.shiro</groupId>
       <artifactId>shiro-spring</artifactId>
       <version>1.4.2</version>
   </dependency>

自定义Realm


/**
 * 自定义的UserRealm
 */
public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;
    @Autowired
    PermService permService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了---授权方法—————————doGetAuthorizationInfo———————————————————————————");
        User user=(User) principalCollection.getPrimaryPrincipal();
        //System.out.println("当前用户-------------------"+user);
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //获取用户所有权限
        List<Perm> listPerms=permService.getPerms(user.getRid());
        //授权
        for (Perm listPerm : listPerms) {
            info.addStringPermission(listPerm.getPerms());
        }
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了---认证方法—————————doGetAuthorizationInfo———————————————————————————");
        AuthenticationInfo authenticationInfo=null;
        UsernamePasswordToken userToken=(UsernamePasswordToken) token;
        String username=userToken.getUsername();
        User user= userService.selUserByusername(username);
        //用户名认证
        if(user==null){
            return null;//数据库中没有登录名为username的人抛出异常 UnknownAccountException
        }
        //密码认证
            authenticationInfo= new SimpleAuthenticationInfo(
                    //参数1:当前用户;
                    //参数2:返回数据库中的正确md5+salt处理后的密码(可根据用户名principal在数据库中查出,
                    //参数3:注册时处理密码的盐
                    //参数4:提供当前realm的名字,this.getName();
                    user,
                    user.getPassword(),
                    ByteSource.Util.bytes("sovzn+shiyaochang"),
                    this.getName());
       return authenticationInfo;
    }
}

Shiro配置类

添加用户的service(MD5+盐+散列):

public void register(User user) {//添加用户
       //加密密码:md5+盐+散列
       Md5Hash md5Hash = new Md5Hash(user.getPassword(),"sovzn+shiyaochang",1024);
       //将加密后的密码赋给用户
       user.setPassword(md5Hash.toHex());
     userDao.saveUser(user);
   }

shiro配置:

注意:在web环境下,springboot会自动将创建的DefaultWebSecurityManager对象注入到SecurityUntils中,不用我们进一步给SecurityUtils注入。


@Configuration
public class ShiroConfig {

    //1.创建realm需要自定义
    @Bean(name = "userRealm")//加@Bean交给spring来托管
   public UserRealm userRealm(){
        UserRealm userRealm=new UserRealm();
        //修改realm的默认凭证校验匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置加密算法为md5
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //设置散列次数
        hashedCredentialsMatcher.setHashIterations(1024);
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return  userRealm;
   }
    //2.创建安全管理器DefaultWebSecurityManager
    // web环境下不能创建SecurityManager,只能创建DefaultWebSecurityManager
    //---------------------且会自动注入给SecurityUntils--------------------
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager =new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //3.ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager)
    {
        ShiroFilterFactoryBean bean=  new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
/**
         * anon:无序认证就可以访问
         * authc:必须认证才能访问
         * user:必须拥有了“记住我”功能才能用
         * perms:拥有对某个资源的权限才能访问
         * roles:拥有某个角色权限才能访问
         */
        Map<String,String> filterMap=new LinkedHashMap<>();
        //filterMap.put("/*","anon");//所有请求都可访问
        //添加拦截过滤的跳转连接
        filterMap.put("/toindex","authc");//管理用户
        filterMap.put("/toadduser","perms[User:adduser]");//添加用户
        filterMap.put("/userslist","perms[User:listuser]");//用户列表
        //添加授权
         filterMap.put("/addUser","perms[admin:pers]");
         //没有授权要跳转的页面
         bean.setUnauthorizedUrl("/to401");
        //没有认证要跳转的页面x
         bean.setLoginUrl("/to404");
         bean.setFilterChainDefinitionMap(filterMap);
         return bean;

    }
    //整合ShiroDialect,用户整合shiro和thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
     return  new ShiroDialect();
    }

}

登录和退出


@Controller
public class LoginController {
    @Autowired
    UserService userService;
    @RequestMapping("/login")
  public String login(@RequestParam("username") String username,
                      @RequestParam("password") String password,
                      Model model, HttpSession session ){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据
       UsernamePasswordToken token= new UsernamePasswordToken(username,password);
       try{
           subject.login(token);
           User user=userService.selUserByusername(username);
           session.setAttribute("loginUser",user.getName());
           return "index";
       }catch (UnknownAccountException e){
           model.addAttribute("msg","提示:用户名错误 φ(* ̄0 ̄)");
           return "login";
       }
        catch (IncorrectCredentialsException e){
           model.addAttribute("msg","提示:密码错误 φ(* ̄0 ̄)");
           return "login";
       }
}
    @RequestMapping("/logout")   //退出登录
    public String login(){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //退出
        subject.logout();
        return "login";
    }

}