springboot整合shiro的使用

shiro的原理已经有博客了,自己写可以问度娘

此处直接描述实际使用

一、pom.xml引包

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

二、三件套

ShiroConfig 
@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) {
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
        /**静态文件css及图片*/
        filterChainDefinitionMap.put("/static/**", "anon");
        /**webservice服务*/
        filterChainDefinitionMap.put("/services/**", "anon");
        filterChainDefinitionMap.put("/token/**", "anon");
        filterChainDefinitionMap.put("/swagger-ui.html", "anon");
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/v2/**", "anon");
        filterChainDefinitionMap.put("/swagger-resources/**", "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;
    }

    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }


    @Bean
    public DefaultWebSecurityManager securityManager(){
            DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }
}
MyShiroRealm 
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserInfoService userInfoService;
    /***授权方法*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        log.info("开始授权 --> MyShiroRealm.doGetAuthorizationInfo()");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        UserInfo userInfo  = (UserInfo)principal.getPrimaryPrincipal();
        for(SysRole role:userInfo.getRoleList()){
            authorizationInfo.addRole(role.getRole());
            for(SysPermission p:role.getPermissions()){
                authorizationInfo.addStringPermission(p.getPermission());
            }
        }
        log.info("结束成功!");
        return authorizationInfo;
    }

    /**认证方法*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info("开始认证 --> MyShiroRealm.doGetAuthenticationInfo()");
        //获取用户的输入的账号.
        String username = (String)token.getPrincipal();
        System.out.println(token.getCredentials());
        //通过username从数据库中查找 User对象,如果找到,没找到.
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        log.info("认证 --> 通过账户查询入参"+username);
        UserInfo userInfo = userInfoService.findByUsername(username);
        log.info("认证 --> 通过账户查询出参"+ JSON.toJSONString(userInfo));
        if(userInfo == null){
            log.info("认证失败!");
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassword(), //密码
                ByteSource.Util.bytes(userInfo.getSalt()),//salt=username+salt
                getName()  //realm name
        );
        log.info("认证成功!");
        return authenticationInfo;
    }
}

给shiro添加token,这时token中的用户才会执行认证授权的流程

    @ApiOperation("登陆获取token")
    @PostMapping("/login")
    @LoginToken
    public Object login(@RequestParam("username") String username, @RequestParam("password") String password) {

        JSONObject jsonObject = new JSONObject();
        UserInfo userInfo = userInfoService.findByUsername(username);
        if (userInfo == null) {
            jsonObject.put("message", "登录失败,用户不存在");
            return jsonObject;
        } else {
            EncryptUtil encryptUtil = EncryptUtil.getInstance();
            String passcode = encryptUtil.MD5(encryptUtil.Base64Encode(password) + userInfo.getSalt());
            //校验登陆密码加盐的一致性
            if (!userInfo.getPassword().equals(passcode)) {
                jsonObject.put("message", "登录失败,密码错误");
                return jsonObject;
            } else {
                //shiro的token
                //添加用户认证信息
                Subject subject = SecurityUtils.getSubject();
                UsernamePasswordToken shiroToken = new UsernamePasswordToken(userInfo.getUsername(),userInfo.getPassword());
                //进行验证,这里可以捕获异常,然后返回对应信息
                subject.login(shiroToken);

                SignInReq sign = new SignInReq();
                sign.setId(Integer.toString(userInfo.getUid()));
                sign.setUserName(userInfo.getUsername());
                //此处的密码是加盐加密过后的
                sign.setPassword(userInfo.getPassword());
                long now = System.currentTimeMillis();
                String dateStr = DateUtil.parseDateToStr(new Date(now+expireTime), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
                String token = JwtTokenUtil.createJWT(expireTime, sign);
                jsonObject.put("token", token);
                jsonObject.put("expireTime",dateStr);
                jsonObject.put("sign", sign);
                return jsonObject;
            }
        }
    }

当然权限crud的自己来一套

最后就可以用了,哈哈

猜你喜欢

转载自www.cnblogs.com/h-c-g/p/11018415.html