springboot快速和shiro框架集成

一个人想着一个人 提交于 2019-12-01 15:24:56

1.pom引入依赖

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

2.Ream实体类

package com.test.test.controller;//package com.shiro.shiro.config;

import com.test.test.entity.SysUser;
import com.test.test.mapper.SysUserDao;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.util.StringUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

//@Service
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;

    //ConcurrentHashMap()在jdk1.5之后推出,在1.8和1.8之后
    //添加了红黑树
    /*private Map<String, SimpleAuthorizationInfo> authMap=
            new ConcurrentHashMap<String, SimpleAuthorizationInfo>();*/

    /***
     * 完成授权信息的获取以及封装.
     * 此方法何时调用?(执行授权检测时调用)
     *
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
//        System.out.println("realm.doGetAuthorizationInfo");
//        //1.获取登陆用户身份信息,(基于登录认证时传递的主身份)
//        String username=
//                (String)principals.getPrimaryPrincipal();
//        //查询缓存中是否有这个
//        /*if(authMap.containsKey(username))
//            return authMap.get(username);*/
//        //2.查找用户的权限信息
//        List<String> list=//sys:user:update,sys:user:view,....,
//                sysUserDao.findUserPermissions(username);
//        System.out.println("list="+list);
//        //去重去空
//        Set<String> permissions=new HashSet<String>();
//        for(String permission:list){
//            if(!StringUtils.isEmpty(permission)){
//                permissions.add(permission);
//            }
//        }
//        System.out.println("====查询认证信息");
//        //3.对权限信息进行封装
//        SimpleAuthorizationInfo info=
//                new SimpleAuthorizationInfo();
//        info.setStringPermissions(permissions);
//        /*authMap.put(username, info);*/
//        return info;
        return null;
    }
    /**
     * 完成认证信息的获取以及封装
     * 此方法何时调用?(执行登陆认证时调用)
     * @param
     * //用于接收用户身份以及凭证信息的对象(用户输入的)
     *
     * @return AuthenticationInfo
     * 封装了认证信息的对象(从数据库查询到的)
     *
     * client-->controller-->service-->realm
     */
    @Override
    protected AuthenticationInfo
    doGetAuthenticationInfo(
            AuthenticationToken token)
            throws AuthenticationException {
        System.out.println("进行身份认证");
        //1.获取用户身份信息
        UsernamePasswordToken uToken=
                (UsernamePasswordToken)token;
        String username=uToken.getUsername();
        //String username=token.getPrintcipal();
        //2.基于用户身份查询数据库信息

        SysUser sysUser = sysUserDao.findUserByUserName(username);
        if(sysUser==null)
            throw new UnknownAccountException("密码或账号错误");
        if(sysUser.getValid()==0){
            throw new LockedAccountException("用户被锁定");
        }
        //3.对查询结果进行封装.
        //3.1获取用户salt值,并将其转换为一个字节源对象
        ByteSource byteSource=
                ByteSource.Util.bytes(sysUser.getSalt());
        //3.2对用户信息进行封装返回.
        AuthenticationInfo info=
                new SimpleAuthenticationInfo(
                        sysUser.getUsername(), //主身份
                        sysUser.getPassword(), //已加密的密码
                        byteSource,//salt对应的字节源对象
                        getName());//realm 的名字
        return info;
    }


    /**
     * 设置凭证(密码)匹配器
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher hMatcher = new HashedCredentialsMatcher();
        //设置加密算法
        hMatcher.setHashAlgorithmName("MD5");
        //设置加密次数
        //hMatcher.setHashIterations(5);

        super.setCredentialsMatcher(hMatcher);
    }

}

3.配置类

package com.test.test.controller;//package com.shiro.shiro;

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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.apache.shiro.mgt.SecurityManager;

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

@Configuration

public class SharioConfig001 {
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/html/**", "anon");
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     * )
     * @return
     */

    @Bean
    public UserRealm userRealm(){
        UserRealm myShiroRealm = new UserRealm();
//        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());
        return securityManager;
    }


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

    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
        mappings.setProperty("UnauthorizedException","/user/403");
        r.setExceptionMappings(mappings);  // None by default
        r.setDefaultErrorView("error");    // No default
        r.setExceptionAttribute("exception");     // Default is "exception"
        //r.setWarnLogCategory("example.MvcLogger");     // No default
        return r;
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!