栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot整合shiro

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot整合shiro

shiro知识点快速入门

整合

1.搞一个@Configuration注解的类,有这个注解项目启动自动执行
描述:这个类自动拦截过滤所有的请求做不同的处理,当调用Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);的时候会触发SecurityManager安全管理器的Authenticator认证器的doGetAuthenticationInfo方法来认证

@Configuration //相当于过去的xml   
public class SpringShiroConfig {

    
    @Bean //
    public ShiroFilterFactoryBean shiroFilter(){
        //实例化对象
        ShiroFilterFactoryBean shiroFilterFactoryBean =
                new ShiroFilterFactoryBean();
        //配置当前shiro使用securityManager
        //
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        //配置未认证通过认证跳转的地址
        shiroFilterFactoryBean.setLoginUrl("/html/login.html");
        //认证成功后,默认跳转地址
        //shiroFilterFactoryBean.setSuccessUrl("");
        //访问未授权的url时跳转地址
        shiroFilterFactoryBean.setUnauthorizedUrl("/html/unauthorized.html");
        //定义放行拦截规则   =号后面配置任意一个字符串都是代表一个底层filter一定不能写错
         // /html/login.html=anon   // anon  不需要认证,就可以访问地址  放行地址
         // /user/logout = logout  // 用户注销配置
         
        Map filterChainDefinitionMap =new linkedHashMap();//hashMap   不要使用new HashMap() 无序的  linkedHashMap获取时会按照放入的顺序
        //放行配置
        filterChainDefinitionMap.put("/html/login.html","anon");
        filterChainDefinitionMap.put("/user/login","anon");
        filterChainDefinitionMap.put("/user/add","anon");
        filterChainDefinitionMap.put("/css
    @Bean
    public DefaultWebSecurityManager  securityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager =
                new DefaultWebSecurityManager();
        //依赖注入自定义realm
        defaultWebSecurityManager.setRealm(myCustomRealm());
        return defaultWebSecurityManager;
    }

    
    @Bean
    public MyCustomRealm myCustomRealm(){
        MyCustomRealm myCustomRealm = new MyCustomRealm();
        myCustomRealm.setCredentialsMatcher(credentialsMatcher());
        return myCustomRealm;
    }

    
    @Bean
    public HashedCredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher =
                new HashedCredentialsMatcher();
        //设置加密算法
        hashedCredentialsMatcher.setHashAlgorithmName(BussinessConstant.CredentialsMatcher.HASHEDAGRITHMNAME);
        //设置哈希次数  增加破解难度
        hashedCredentialsMatcher.setHashIterations(BussinessConstant.CredentialsMatcher.HASHEDINTERATIONS);
        return hashedCredentialsMatcher;
    }
}

2.认证和授权方法
描述:特定情况下触发这两个方法的时候

触发情况:

1.doGetAuthenticationInfo执行时机如下

当调用Subject currentUser = SecurityUtils.getSubject();

currentUser.login(token);

2.doGetAuthorizationInfo执行时机有三个,如下:

1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”):自己去调用这个是否有什么角色或者是否有什么权限的时候;

2、@RequiresRoles(“admin”) :在方法上加注解的时候;

3、[@shiro.hasPermission name = “admin”][/@shiro.hasPermission]:在页面上加shiro标签的时候,即进这个页面的时候扫描到有这个标签的时候。

方法:

public class MyCustomRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //该方法执行时,认证一定是通过的,如果认证不过,该方法不会执行
          // 获取认证时放入的第一个参数  
        User user = (User)principalCollection.getPrimaryPrincipal();
        String userName = user.getUserName();
        SimpleAuthorizationInfo simpleAuthorizationInfo =new SimpleAuthorizationInfo();
        List roleList = userService.queryRoleListByUserName(userName);
        List menuList = userService.queryMenuListByUserName(userName);
        //添加角色
        if(!CollectionUtils.isEmpty(roleList)){
            for (Role role : roleList) {
                simpleAuthorizationInfo.addRole(role.getRoleKey());
            }
        }
        //添加权限
        if(!org.springframework.util.CollectionUtils.isEmpty(menuList)){
            for (Menu menu : menuList) {
                if(!StringUtils.hasLength(menu.getPerms())){
                    simpleAuthorizationInfo.addStringPermission(menu.getPerms());
                }
            }
        }
        return simpleAuthorizationInfo;
    }

    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
      //获取用户名
        String userName =  (String)authenticationToken.getPrincipal();
        //根据用户获取用户信息
        User user = userService.queryUserByUserName(userName);
        //如果对象为空,直接账号错误  代码终止运行
        if(user==null){
            throw new AccountException();
        }
        //获取加密密码
        String password = user.getPassword();
        //获取盐值
        String salt = user.getSalt();
        return new SimpleAuthenticationInfo(user,//第一参数 放主要的信息(用户信息)  当认证成功后,可以通过Subject获取
                password,//第二参数  加密密码 用户注册时,要使用shiro提供的加密算法SHA-512,带上密码和随机盐值经过10次哈希后的结果
                ByteSource.Util.bytes(salt),//第三个参数  随机盐值
                this.getName());  }
}

加密工具:

public class BussinessConstant {

    
    public interface CredentialsMatcher{
        String  HASHEDAGRITHMNAME="SHA-512";
        int    HASHEDINTERATIONS=1024;
    }
}
登陆细节:

1.触发认证的登录方法:

 
    @PostMapping("login")
    public String login(String userName,String password){
        //收集用户信息
        UsernamePasswordToken usernamePasswordToken =
                new UsernamePasswordToken(userName, password);
        //获取当前主体(当前用户)
        Subject currentUser = SecurityUtils.getSubject();
        String errorInfo = "";
        try {
            //登录
            currentUser.login(usernamePasswordToken);
            //获取认证成功的用户信息
            User user =  (User)currentUser.getPrincipal();
            //获取安全session
            Session session = currentUser.getSession();
            //存入用户信息
            session.setAttribute("userInfo",user);
            //认证成功后  重定向到部门查询
            return "redirect:/dept/queryAll";
        }catch (AccountException e) {
            e.printStackTrace();
            errorInfo= "1";
        }catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            errorInfo= "2";
        } catch (AuthenticationException e) {
            e.printStackTrace();
            errorInfo= "3";
        }
         return "redirect:/html/login.html?errorInfo="+errorInfo;
    }

2.这里使用的是实体类做sql执行返回值,需要设置实体类和实体类对应的属性,注意sql查询操作的元素要与实体类属性名字相同,强制的,一般sql都是复杂的不会相同,有两个方法可以是两者相同

 1.通过resultMap标签设置实体类和sql查询的数据
 
 2. 改别名
 select role_id roleId,role_name as roleName,role_key roleKey from sys_role




sql语句



    
        select user_id userId,user_name  userName,login_Name loginName,password,salt
        from sys_user where del_flag=0 and status=0
        
            and user_name=#{userName}
        

    
授权: 获取角色和权限数据

这边是通过方法上的限制去处理权限,当要访问某个方法得时候会先去查看你这个用户得权限,有对应得授权方法,通过方法上的 这三种注解
@RequiresPermissions(“dept:query”) // 判断当前用户是否拥有权限dept:query,如果有就可以执行该方法
@RequiresPermissions(“dept:queryById”) //判断当前用户是否拥有角色代理商,如果有就可以执行该方法
@RequiresRoles(“guanliyuan”) //判断当前用户是否拥有角色管理员,如果有就可以执行该方法

去触发查询权限函数

 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //该方法执行时,认证一定是通过的,如果认证不过,该方法不会执行
          // 获取认证时放入的第一个参数  
        User user = (User)principalCollection.getPrimaryPrincipal();
        String userName = user.getUserName();
        SimpleAuthorizationInfo simpleAuthorizationInfo =new SimpleAuthorizationInfo();
        List roleList = userService.queryRoleListByUserName(userName);
        List menuList = userService.queryMenuListByUserName(userName);
        //添加角色
        if(!CollectionUtils.isEmpty(roleList)){
            for (Role role : roleList) {
                simpleAuthorizationInfo.addRole(role.getRoleKey());
            }
        }
        //添加权限
        if(!org.springframework.util.CollectionUtils.isEmpty(menuList)){
            for (Menu menu : menuList) {
                if(!StringUtils.hasLength(menu.getPerms())){
                    simpleAuthorizationInfo.addStringPermission(menu.getPerms());
                }
            }
        }
        return simpleAuthorizationInfo;
    }
菜单角色权限sql
1查询用户角色权限


 
         select menu_id menuId,menu_name menuName,perms from sys_menu m where visible=0 and exists(
       select 1 from sys_role_menu rm where  exists(
        select 1 from   sys_user_role ur where user_id=
         (select user_id  from sys_user where user_name=#{userName}  and del_flag=0  and status=0)
         and rm.role_id=ur.role_id
       ) and rm.menu_id=m.menu_id
     )
    
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759337.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号