小白使用shiro安全框架|SpringBoot框架整合Shiro安全框架|使用Shiro安全框架实现用户用户角色接口权限管理|解决Shiro安全框架多角色权限问题

前情提示:
1、我的数据库一共有4种用户类型表:student、school、company、admin,每张表都有属性role,以此让shiro获得用户角色。
2、因为shiro的用户权限是默认交集的,即一个接口配置多个用户角色的话就时必须时全部都满足这个角色才能访问。因此我进行了第四步配置。如果没有这个问题的话可以忽略第四步。
3、我实现的方法比较笨拙,仅供参考。有啥问题可以留言,共同进步哈。

一、新建一个对象User类

public class User {
    private Integer id;
    private String password;
    private String role;
    public void setId(Integer id) {
        this.id = id;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public void setUserSalt(String userSalt) {
        this.userSalt = userSalt;
    }
    public Integer getId() {
        return id;
    }
    public String getPassword() {
        return password;
    }
    public String getRole() {
        return role;
    }
    public String getUserSalt() {
        return userSalt;
    }
    private String userSalt;
}

二、新建一个文件夹Config,在其中新建一个UserRealm.java文件

package com.example.config;
import com.example.pojo.*;
import com.example.service.AdminService;
import com.example.service.CompanyService;
import com.example.service.SchoolService;
import com.example.service.StudentService;
import org.apache.shiro.authc.Account;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import java.util.HashSet;
import java.util.Set;
public class UserRealm extends AuthorizingRealm {
    @Autowired
    AdminService adminService;
    @Autowired
    CompanyService companyService;
    @Autowired
    SchoolService schoolService;
    @Autowired
    StudentService studentService;

    //返回当前realm的一个自定义名称
    public String getName() {
        return "UserRealm";
    }

    /**
     * 获取授权信息
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了==》》授权doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取到当前用户
        User user = (User) principalCollection.getPrimaryPrincipal();
//        //赋予用户角色
        //Role role = adminService.findRoleByAccountName(account.getUsername());
        Set<String> roleSet = new HashSet<String>();
        roleSet.add(user.getRole());
        info.setRoles(roleSet);
        return info;
    }

    /**
     * 认证
     * <p>
     * 获取认证的安全信息(从数据库查询用户的正确信息)
     *
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了==》》doGetAuthenticationInfo");
        //从token中获取用户名
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        String username = userToken.getUsername();
        //用户名,密码,数据库中取
        Admin admin = adminService.queryByUserName(Integer.valueOf(username));
        Company company = companyService.queryByUserName(Integer.valueOf(username));
        School school = schoolService.queryByUserName(Integer.valueOf(username));
        Students st = studentService.queryByUserName(Integer.valueOf(username));
        if (admin == null) {
            if (company == null) {
                if (school == null) {
                    if (st == null) {
                        return null;//用户名不存在
                    }
                }
            }
        }
        //获取session
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        User user=new User();
        if (admin != null) {
            session.setAttribute("loginUser", admin);
            user.setId(admin.getId());
            user.setPassword(admin.getPassword());
            user.setRole(admin.getRole());
        } else if (company != null) {
            session.setAttribute("loginUser", company);
            user.setId(company.getId());
            user.setPassword(company.getPassword());
            user.setRole(company.getRole());
        } else if (school != null) {
            session.setAttribute("loginUser", school);
            user.setId(school.getId());
            user.setPassword(school.getPassword());
            user.setRole(school.getRole());
        } else   {
            session.setAttribute("loginUser", st);
            user.setId(st.getId());
            user.setPassword(st.getPassword());
            user.setRole(st.getRole());
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
}

三、在文件夹Config新建一个ShiroConfig.java文件

package com.example.config;

import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;


@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean

    //DafaultWebSecurityManager

    //创建realm对象
    //ShiroFilterFactoryBean
    //过滤器
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
//        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//        //设置安全管理器
//        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        //
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        // 存放自定义的filter
        LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
        // 配置自定义 or角色 认证
        filtersMap.put("roles", new MyShiroFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);
       // Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        /*
        anon:无需认证可以访问
        authc:必须认证才能访问
        user:必须拥有 记住我 功能才能用
        perms:拥有对某个资源的权限才能访问
        role:拥有某个角色权限才能访问
         */
        //登录拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
        //用户进入登录界面,无需认证 登陆不拦截
       filterMap.put("/admin/login", "anon");
       filterMap.put("/student/login", "anon");
       filterMap.put("/company/login", "anon");
       filterMap.put("/school/login", "anon");

//        filterMap.put("/**", "authc");
//        //用户进入系统,必须进行登录验证
       System.out.println(filterMap);
        //角色拦截  我只展示部分的
        //admin
        filterMap.put("/admin/showAll", "authc,roles[admin]");
        filterMap.put("/admin/showById", "authc,roles[admin]");
        filterMap.put("/admin/fixPassword", "authc,roles[admin]");
        //company
        filterMap.put("/company/showAll", "authc,roles[admin,school,student]");
        filterMap.put("/company/selectByAll", "authc,roles[admin,school,student]");
        filterMap.put("/company/deleteById", "authc,roles[admin,school]");
        filterMap.put("/company/add", "authc,roles[admin,school]");
        filterMap.put("/company/showById", "authc,roles[company]");
        filterMap.put("/company/fixPassword", "authc,roles[company]");
        filterMap.put("/company/fixMessage", "authc,roles[company]");
        //设置登出
        //filterMap.put("/logout", "logout");
        //设置admin下的某个方法需要某个权限
        // filterMap.put("/sys/admin/find", "perms[admin:find]");
        System.out.println(filterMap);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//        shiroFilterFactoryBean.setLoginUrl();
//        //设置未授权访问的页面路径401(无权限界面)
//        shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");
        return shiroFilterFactoryBean;
    }


    //DefaultWebSecurityManager:2
    @Bean("defaultWebSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("UserRealm")UserRealm userRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //关联userRealm
        defaultWebSecurityManager.setRealm(userRealm);
        return defaultWebSecurityManager;
    }

    //自定义realm
    @Bean("UserRealm")
    public UserRealm getUserRealm() {
        UserRealm userRealm=new UserRealm();
        return userRealm;
    }
}

四、在文件夹Config新建一个MyShiroFilter.java文件

package com.example.config;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

@Configuration
public class MyShiroFilter  extends AuthorizationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

        Subject subject = getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;
        //没有角色限制,没有权限访问
        if (rolesArray == null || rolesArray.length == 0) {
            return false;
        }
        //若当前用户是rolesArray中的任何一个,则有权限访问
        for (int i = 0; i < rolesArray.length; i++) {
            if (subject.hasRole(rolesArray[i])) {
                return true;
            }
        }

        return false;
    }

}

五、在每个登陆接口的service插入语句:

 //shrio验证
        Subject subject= SecurityUtils.getSubject();
        UsernamePasswordToken token =new UsernamePasswordToken(String.valueOf(admin.getId()),admin.getPassword());
        subject.login(token);

Over!!!亲测可用呀

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值