一个关于shiro的编程实践

shiro的demo很多,我也看了很多,基本掌握了用法,而去基于shiro做一部分按需定制的开发还是感觉有些难度.

这个例子是这样的:

1.会员登录前端网站,需按照其等级分配权限,查看网站上的数据(低等级不展示具体数值,反之)

2.管理员等角色登录网站后端,进行后端权限操作分配.(除了样式没设置,其它的都还可以了)

我认为的改变是从ShiroConfiguration这个配置类着手,code 如下

/**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     * <p>
     * Filter Chain定义说明
     * 1、一个URL可以配置多个Filter,使用逗号分隔
     * 2、当设置多个过滤器时,全部验证通过,才视为通过
     * 3、部分过滤器可指定参数,如perms,roles
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //TODO 2019-1-29 17:40
        //将设置url的参数改为application.properties中去配置
        //securityManager改为可选择的进行传入
        //customisedFilter的hashmap传入的url及URLPath...Filter改为参数可传入
        //customisedFilter这个HashMap装配了登录及登录后可未授权页面(admin的配置admin的,member的配置member的)
        //filterChainDefinitionMap
        
        //1.securityManager中的realm按需配置
        //2.shiroFilterFactoryBean中的set...Url为按需配置
        //3.shiroFilterFactoryBean.setFilters(customisedFilter);中的customisedFilter按需配置
        //**customisedFilter为put了仅仅一个"url",value为URL路径匹配过滤器(按需传入)
        //4.shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        //**filterChainDefinitionMap为按需配置



        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/admin/login"); //原为/login
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/admin/"); //原为/index
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unauthorized"); //原为/unauthorized
        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //自定义拦截器
        Map<String, Filter> customisedFilter = new HashMap<>();
        customisedFilter.put("url", getURLPathMatchingFilter());

        //配置映射关系 anon表示不需要权限即可访问
        filterChainDefinitionMap.put("/admin/login", "anon");
//        filterChainDefinitionMap.put("/admin/index", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/admin/config/**", "anon");
        filterChainDefinitionMap.put("/admin/doLogout", "logout");
        ;//后台登出
//      单独放入member的配置中  filterChainDefinitionMap.put("/member/doLogout","logout");//前端客户登出
        filterChainDefinitionMap.put("/admin/**", "url"); //路径/shiro_admin/**全部需要进行权限验证
        //其他资源都需要认证  authc 表示需要认证才能进行访问 user表示配置记住我或认证通过可以访问的地址
        filterChainDefinitionMap.put("/admin/**", "user");
        shiroFilterFactoryBean.setFilters(customisedFilter);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

要分别设定其权限及验证有github上的一些demo可以参考,但不同的是没有了这些路径拦截配置.

ShiroFilterFactoryBean中有些数值的getter setter从这里入手,并重写FilterChainManager应该可以完成路径的自由配置:

同理可得重写ShiroFilterFactoryBean也一样会设定自由路径的配置:

首先第一步,在重写的CustomShiroFilterFactoryBean中,我们要设置参数的可判定性,因为上方中的loginUrl...包括put到filterChainDefinitionMap中的路径等都是固定的,我们要根据判断的用户类型去配给不同的路径.(当然这样做后在实际应用场景中是否能奏效还待考量)

根据这种思路改变的MyRealm

package com.tansuo365.test1.realm;

import com.tansuo365.test1.bean.Member;
import com.tansuo365.test1.bean.User;
import com.tansuo365.test1.entity.MyLoginInstance;
import com.tansuo365.test1.service.*;
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.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private MemberService memberService;//member
    @Autowired
    private UserService userService;//user

    @Autowired
    private MroleService mroleService;//member
    @Autowired
    private RoleService roleService; //user

    @Autowired
    private MemberPermissionService memberPermissionService;//member
    @Autowired
    private PermissionService permissionService;//user

    /*获取授权权限信息*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = null;
        //获取当前登录类型
        String loginType = (String)SecurityUtils.getSubject().getSession().getAttribute("loginType");
        Set<String> permissions = null;
        Set<String> roles = null;

        // 能进入到这里,表示账号已经通过验证了
        String username = (String)principals.getPrimaryPrincipal();

        if(LoginEnum.ADMIN.toString().equals(loginType)){
            permissions = permissionService.listPermissions(username);
            roles = roleService.listRoleNames(username);
        }
        if(LoginEnum.MEMBER.toString().equals(loginType)){
//            Member member = memberService.getByName(username);
            // 通过service获取角色和权限
            permissions = memberPermissionService.listMemberPermissions(username);
            roles = mroleService.listMroleNames(username);
        }
        // 授权对象
        info = new SimpleAuthorizationInfo();
        // 把通过se
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值