Java权限管理系统之代码实现(三)

一、概述

      这篇文章主要总结自己对shiro框架实现登录认证和shiro授权控制过程的学习、实践经验。shiro整合springboot框架实现的过程。现在的工作不会涉及到这些开源框架,有空还是学习、总结一下,提升自己的记忆。

二、shiro过程概述

“Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入Shiro即可”

从外部应用程序的角度来看,shiro完成工作的流程如下图

Subject:主体,代表当前用户,所有的Subject都会绑定到SecurityManager,与Subject所有交互都会委托给SecurityManager。

SecurityManager:安全管理器,即所有与安全相关的操作都会与SecurityManager交互;管理着所有的Subject,可以看出它是shiro的核心。

Realm:域,Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较确定用户身份。也需要从Realm得到用户相应的角色/权限验证用户是否能进行操作。可以把Realm看成DataSources。

三、登录认证/授权

1、收集用户身份/凭证,即用户名和密码。

2、调用Subject.login进行登录,如果失败,可以根据相应的异常,提示用户错误信息。

3、自定义用户Realm类,进行用户认证、授权管理。

Controller层 

@RequestMapping(value = "/login.do")
    public String login(String name, String password, Model model){
        //1.获取Subject
        Subject subject = SecurityUtils.getSubject();
        String password_secrety = EncryptUtil.encryptMD5(password);
        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(name,password_secrety);
        //3.执行登录方法
        try {
            subject.login(token);
            //登录成功
            return "index";
        } catch (UnknownAccountException e) {
            //登录失败:用户名不存在
            model.addAttribute("msg", "用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e) {
            //登录失败:密码错误
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }

自定义Realm实现(public class UserRealm extends AuthorizingRealm)

public class UserRealm extends AuthorizingRealm {
    @Autowired
    private IUserService userSerivce;
    /**
     * 执行授权逻辑
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //添加资源的授权字符串
       // info.addStringPermission("user:add");
        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();
        // 从数据库获取到权限编码,如user:add,这里只实践权限编码的方式
        List<String> permissionList=null;
        //到数据库查询当前登录用户的授权字符串
        permissionList=userSerivce.findAllPermByUserId(user.getUser_id());
        info.addStringPermissions(permissionList);
        return info;
    }
    /**
     * 执行认证逻辑
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        //编写shiro判断逻辑,判断用户名和密码
        //1.判断用户名
        UsernamePasswordToken token = (UsernamePasswordToken)arg0;
        User user = userSerivce.findUserByName(token.getUsername());
        if(user==null){
            //用户名不存在
            return null;//shiro底层会抛出UnKnowAccountException
        }
        //2.判断密码
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

}

编写Shiro配置类(public class ShiroConfig),主要将项目资源初始化、资源过滤等进行配置

@Configuration
public class ShiroConfig {
    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perms: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
		/*filterMap.put("/add", "authc");
		filterMap.put("/update", "authc");*/
        //  filterMap.put("/testThymeleaf", "anon");

        //放行login.html页面,不然不能登录
        filterMap.put("/login.do", "anon");
        //授权过滤器,把需要限制权限的请求按钮都在这边过滤
        //注意:当前授权拦截后,shiro会自动跳转到未授权页面
         filterMap.put("/addUser.do", "perms[user:add]");  //通过该方法,对每一个方法进行权限控制
       // filterMap.put("/update", "perms[user:update]");

        filterMap.put("/*", "authc");
        //修改调整的登录页面
        shiroFilterFactoryBean.setLoginUrl("/logout.do");
        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth.do");

        /**
         * 配置信息加入shiro的过滤器中
         */
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }
    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    /**
     * 创建Realm
     */
    @Bean(name="userRealm")
    public UserRealm getRealm(){
        return new UserRealm();
    }
    /**
     * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

 

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值