shiro:授权,认证总结

1,shiro对象(Relam)的创建步骤

  工具类:目的是自定义(高级定制)授权和认证,

(1)ShiroFilterFactoryBean工厂:——》DefaultWebSecurityManager:-》创建 realm 对象,需要自定义类
  这个类的目的是高级定制一个
ShiroFilterFactoryBean工厂,生产自定义的Realm,
  在这里设置认证和授权
注意:shiro不仅仅要整合spring还要整合thymeleaf

@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean工厂:3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //添加shiro内置过滤器
        /*
        * anon:无需认证就能访问
        * authc:必须认证才能访问
        * user:必须拥有记住我功能才能使用
        * perms:拥有对某个资源的权限才能访问
        * role:拥有某个角色权限才能访问
        * */
        //拦截
        Map<String, String> filterMap=new LinkedHashMap<>();
        //这里面的路径是请求路径
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","authc");

        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录请求
        bean.setLoginUrl("/toLogin");
        //设置未授权页面
        bean.setUnauthorizedUrl("/noauth");


        return bean;
    }

    //DefaultWebSecurityManager:2
    //@Qualifier作用,绑定指定的spring容器里的bean
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联userRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    //创建 realm 对象,需要自定义类 :1
    @Bean(name = "userRealm")//被spring容器接管
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合ShiroDialect:用来整合shiro thymleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

}

 

 

  (2)继承抽象类AuthorizingRealm,里面封装的就是自定义的ShiroFilterFactoryBean工厂生产后的产物

     在这个类自定义和重写认证和授权

 

    //自定义的 UserRealm
    public class UserRealm extends AuthorizingRealm {

        @Autowired
        UserService userService;

        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("执行了=>授权AuthorizationInfo");

            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //info.addStringPermission("user:add");//授权写死,便于实验

            //拿到当前登录的这个对象
            Subject subject = SecurityUtils.getSubject();
            User currentUser =(User) subject.getPrincipal();//拿到user对象

            //设置当前用户的权限,数据从数据库取
            info.addStringPermission(currentUser.getPerms());

            return info;
        }


        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("执行了=>认证AuthenticationInfo");

            UsernamePasswordToken userToken= (UsernamePasswordToken) token;
            //从真实数据库中拿数据
            User user = userService.queryUserByName(userToken.getUsername());
            if (user==null){
                return null;
            }

            //密码认证,shiro做
            return new SimpleAuthenticationInfo(user,user.getPwd(),"");

        }
    }

 

到这里shiro的认证和授权就结束了,最后就是结合controller层去去在前端体现了

controller层小demo

@Controller
public class MyController {
    //首页
    @RequestMapping({"/","/index"})
    public String toIndex(Model model){
        model.addAttribute("msg","Hello shiro");
        return "index";
    }

    @RequestMapping("user/add")
    public String add(){

        return "user/add";
    }

    @RequestMapping("user/update")
    public String update(){

        return "user/update";
    }

    @RequestMapping("toLogin")
    public String toLogin(){

        return "login";
    }

    @RequestMapping("login")
    public String login(String username,String password,String remember,Model model){
        //获取当前用户
        Subject subject= SecurityUtils.getSubject();
        if (remember!=null){
            subject.isRemembered();
        }
        System.out.println(remember);
        //封装用户的登陆数据
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);

        try{
            subject.login(token);//执行登录方法,如果不报异常就success
            return "index";
        }catch (UnknownAccountException e){//用户名不存在
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){//密码不存在
            model.addAttribute("msg","密码错误");
            return "login";
        }

    }

    //没有权限提示界面
    @RequestMapping("/noauth")
    @ResponseBody
    public String unauthorized(){

        return "未经授权无法访问此页面";
    }

    //注销
    @RequestMapping("logout")
    public String logout(){
        //获取当前用户
        Subject currentSubject= SecurityUtils.getSubject();
        //注销
        currentSubject.logout();
        return "redirect:/  ";
    }

}

功能:此demo基本实现了用户的权限管理(如:普通用户,管理员),登陆注销也是结合了shiro,通过判断是否认证动态展示登录和注销,其他功能模块也是通过shiro判断每个用户在后台所拥有的权限,来确定用户所能访问的界面;

 

demo效果展示

1,游客界面

 

 

 

2,登录界面 

 

3,不同角色访问不同的功能页面

3.1 用户1(add权限)

 

 

 

 

3.12用户2(update权限)

 

 

 

 

4,注销(删除subject相当于删除session),返回游客状态

 

数据库

 

posted @ 2021-01-06 11:53  凸然猿  阅读(184)  评论(0编辑  收藏  举报