springboot整合shiro篇1--配置shiro

1:引入spring-shiro 依赖

        <!--权限拦截-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

2:配置shiro的生命周期和切面拦截

@Configuration
@Slf4j
public class ShiroHelperConfig {


    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        log.info("lifecycleBeanPostProcessor bean");
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        log.info("lifecycleBeanPostProcessor bean");
        return creator;
    }
}

3:配置shiro的安全管理器

/**
 * shiro configuration
 **/
@Configuration
@Slf4j
@AutoConfigureAfter(value = {ShiroHelperConfig.class})
public class ShiroConfig {


    @Bean(name = "securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") TourismAuthorizingRealm authRealm,
                                           @Qualifier("cookieRememberMeManager") CookieRememberMeManager cookieRememberMeManager) {
        log.info("securityManager()");
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();


        // 设置rememberMe管理器
        securityManager.setRememberMeManager(cookieRememberMeManager);

        // 设置realm,解决doGetAuthorizationInfo方法没有调用问题
        securityManager.setRealm(authRealm);

        return securityManager;
    }

    /**
     * realm
     *
     * @return
     */
    @Bean(name = "authRealm")
    public TourismAuthorizingRealm tourismAuthorizingRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher matcher) {
        log.info("tourismAuthorizingRealm bean");
        TourismAuthorizingRealm myAuthorizingRealm = new TourismAuthorizingRealm();
        // 设置密码凭证匹配器
        myAuthorizingRealm.setCredentialsMatcher(matcher);
        return myAuthorizingRealm;
    }


    /**
     * cookie对象;
     *
     * @return
     */
    public SimpleCookie rememberMeCookie() {
        // 这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //记住我cookie生效时间30天(259200)单位秒;
        simpleCookie.setMaxAge(259200);
        return simpleCookie;
    }

    /**
     * 记住我管理器 cookie管理对象;
     */
    @Bean(name = "cookieRememberMeManager")
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        return cookieRememberMeManager;
    }

    /**
     * 密码匹配凭证管理器
     *
     * @return
     */
    @Bean(name = "hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName(PasswordUtils.ALGORITHM_NAME);
        hashedCredentialsMatcher.setHashIterations(PasswordUtils.HASH_ITERATIONS);// 散列的次数,比如散列两次,相当于
        return hashedCredentialsMatcher;
    }


    /**
     * 开启shiro aop注解支持.
     * <p>
     * 使用代理方式;所以需要开启代码支持;
     * Controller才能使用@RequiresPermissions
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
            @Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }



4:配置shiro的校验器

public class TourismAuthorizingRealm extends AuthorizingRealm {

    private final static Logger logger = LoggerFactory.getLogger(TourismAuthorizingRealm.class);

    @Autowired
    @Qualifier("userService")
    private UserService userService;

    //shiro的权限配置方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        logger.info("权限配置-->doGetAuthorizationInfo");


        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        logger.info("----------------------------->" + principals.getPrimaryPrincipal());

        User user = (User) principals.getPrimaryPrincipal();
        logger.info("doGetAuthorizationInfo() user: {}", user);
        List<Role> roles = userService.getRoles(user.getUserId());
        for (Role role : roles) {

            authorizationInfo.addRole(role.getRoleName());

            // 如果有权限,应该增加所有角色对应的权限
            // authorizationInfo.addStringPermission()
        }

        logger.info("用户: {},具有的角色: {}", user.getUserName(), authorizationInfo.getRoles());
        logger.info("用户: {},具有的权限: {}", user.getUserName(), authorizationInfo.getStringPermissions());

        return authorizationInfo;
    }

    //shiro的身份验证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        logger.info("正在验证身份...");
        SimpleAuthenticationInfo info = null;

        //将token转换成UsernamePasswordToken
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        //从转换后的token中获取用户名
        String username = upToken.getUsername();
        //查询数据库,得到用户
        User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getUserName, username));
        if (user == null) {
            logger.info("没有用户: {}", username);
            return null;
        }

        //得到加密密码的盐值
        ByteSource salt = ByteSource.Util.bytes(user.getUserSalt());

        logger.info("加密密码的盐: {}", salt);
        //得到盐值加密后的密码: 只用于方便数据库测试,后期不会用到。
        Object md = new SimpleHash(PasswordUtils.ALGORITHM_NAME, upToken.getPassword(), salt, PasswordUtils.HASH_ITERATIONS);
        logger.info("盐值加密后的密码: {}", md);
        //TODO: 用户名;用户密码;加密盐;realm name
        info = new SimpleAuthenticationInfo(user, user.getUserPassword(), salt, getName());
        return info;
    }


5:配置用户的加密方式

/**
 * password utils
 **/
public class PasswordUtils {

    public static final String ALGORITHM_NAME = "MD5";

    public static final int HASH_ITERATIONS = 1024;

    /**
     * 重新计算md5值
     *
     * @param password
     * @param salt
     * @return
     */
    public static String renewPassword(String password, String salt) {
        SimpleHash md5hash = new SimpleHash(
                ALGORITHM_NAME, password, salt, HASH_ITERATIONS);
        return md5hash.toHex();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值