springboot整合shiro---认证及授权

最近来新项目, 后台管理, 说道管理, 肯定是需要权限; 又把之前看的shiro拿出来用, 因为之前用的springMVC, 懂的也是半吊子, 这次用springboot也费老劲了, 但是还是让我把它的基本用法搞懂了, 下面分享下;

1.上jar包


        
            org.apache.shiro
            shiro-spring
            1.4.0
        

2.shiro配置类

package cn.cooplan.data_statistical.config;

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author MaoLG
 * @Date 2018/11/17  11:24
 */
@Configuration
public class ShiroConfig {


    /**
     * LifecycleBeanPostProcessor,这是个DestructionAwareBeanPostProcessor的子类,
     * 负责org.apache.shiro.util.Initializable类型bean的生命周期的,初始化和销毁。
     * 主要是AuthorizingRealm类的子类,以及EhCacheManager类。
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * ShiroRealm,这是个自定义的认证类,继承自AuthorizingRealm,
     * 负责用户的认证和权限的处理,可以参考JdbcRealm的实现。
     * 这个类是我自己定义的, 因为要根据自己实际需求来进行权限校验
     */
    @Bean(name = "shiroRealm")
    @DependsOn("lifecycleBeanPostProcessor")
    public ShiroRealm shiroRealm() {
        ShiroRealm realm = new ShiroRealm();
        return realm;
    }

    /**
     * SecurityManager,权限管理,这个类组合了登陆,登出,权限,session的处理,是个比较重要的类。
     *
     * @return
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm());
        return securityManager;
    }

    /**
     * ShiroFilterFactoryBean,是个factorybean,为了生成ShiroFilter。
     * 它主要保持了三项数据,securityManager,filters,filterChainDefinitionManager。
     * 该类类似springmvc配置的访问权限设置
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());

        //url权限配置, url为controller设置的可访问的路径 ps:url可以使用*(通配符设置)
        Map filterChainDefinitionManager = new LinkedHashMap();
        //可以匿名访问的权限 anon:不登录也可访问
        filterChainDefinitionManager.put("/user/login", "anon");
        //必须登录的权限 authc:必须登录才能访问的权限
        filterChainDefinitionManager.put("/user/test", "authc");
        //退出登录 logout:退出登录, shiro帮我们实现, 该路径方法可不编写任何逻辑,可清楚shiro记录的认证
        // 每次去认证的时候, 如果不调用该接口, 不会访问数据库去认证 会直接从shiro的缓存中拿取认证信息, 在适当情况调用该接口
        filterChainDefinitionManager.put("/user/logout", "logout");

        //权限访问, 不能动态获取, 代码写死, 没找到动态获取方法
        filterChainDefinitionManager.put("/user/test", "perms[测试]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);

        return shiroFilterFactoryBean;
    }

    /**
     * DefaultAdvisorAutoProxyCreator,Spring的一个bean,由Advisor决定对哪些类的方法进行AOP代理。
     */
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    /**
     * AuthorizationAttributeSourceAdvisor,shiro里实现的Advisor类,
     * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法。
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();
        aASA.setSecurityManager(securityManager());
        return aASA;
    }
}

3.自定义realm

package cn.cooplan.data_statistical.config;

import cn.cooplan.data_statistical.dao.PermissionDao;
import cn.cooplan.data_statistical.dao.UserDao;
import cn.cooplan.data_statistical.pojo.Permission;
import cn.cooplan.data_statistical.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 自定义realm
 *
 * @Author MaoLG
 * @Date 2018/11/17  13:03
 */
public class ShiroRealm extends AuthorizingRealm {
    //读取用户权限,我这里没有角色表, 具体根据自己实际需求编写
    @Autowired
    private PermissionDao permissionDao;

    /**
     * 授权
     * 实现授权具体业务
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获得登录时提供的重要凭证, 这里获得的是登录账号
        String username = (String) principalCollection.getPrimaryPrincipal();
        //查询到该账号下所有的权限
        List permissions = permissionDao.selectUserOwnPermission(username);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      //把用处所有权限加在SimpleAuthorizationInfo 对象中, shiro自己来读取对比权限
        for (Permission permission: permissions){
            info.addStringPermission(permission.getName());
        }
      //如果有角色的需要, 调用info.addRole("角色"); 同权限一个道理
        return info;
    }

    /**
     * 认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) 
throws AuthenticationException {
        SimpleAuthenticationInfo info = null;
        try {
            //强转UsernamePasswordToken 类型
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            //获得登录账号
            String username = token.getUsername();

            char[] pwd = token.getPassword();
            //获得登密码
            String password = String.valueOf(pwd);
            //shiro默认配置回去找t_user表 来查询 , 也可根据自己实际业务编写
            info = new SimpleAuthenticationInfo(username, password, getName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return info;
    }
}

这里没有使用rememberMe(记住我--实现自动登录), 有需要的大家自行先百度, 后期如果使用到会更新上去

你可能感兴趣的:(springboot整合shiro---认证及授权)