SpringCloud微服务之整合shiro

1.application.yml

 2.pom.xml

3.编写自定义shiro realm

/**
 * FileName: MyShiroRealm
 * Date:     2018/12/5 15:07:07
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.XXXX.demo.shiro.config;

import com.XXXX.demo.api.vo.RoleVo;
import com.XXXX.demo.api.vo.UserVo;
import com.XXXX.demo.client.core.UserClientService;
import com.XXXX.demo.client.redis.RedisClient;
import com.XXXX.demo.common.pojo.resp.RespMsgBean;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 〈一句话功能简述〉<br>
 * 自定义shiro realm
 * @create 2018/12/5 15:07:07
 * @since 1.0.0
 */
@Component
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserClientService userClientService;

    @Autowired
    private RedisClient redisClient;

    @Override
    public String getName() {
        return "MyShiroRealm";
    }

    /**
     * 身份认证
     * @prama
     * @return
     * @date 2018/12/5 15:40
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("————身份认证方法————");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String name = token.getUsername();
        // 先从redis中获取用户信息,从数据库获取对应用户名密码的用户
        UserVo user = checkUserFromRedis(name);
        if (user.getPassword() == null || user == null) {
            throw new AccountException("用户名不正确!");
        } else if (!user.getPassword().equals(new String((char[]) token.getCredentials()))) {
            throw new AccountException("密码不正确!");
        }
        return new SimpleAuthenticationInfo(token.getPrincipal(), user.getPassword(), getName());
    }

    /**
     * 权限认证
     * @prama
     * @return
     * @date 2018/12/5 15:40
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        //获取登录用户名
//        String name= (String) principalCollection.getPrimaryPrincipal();
//        //查询用户名称
//        RespMsgBean respMsgBean = userClientService.findByName(name);
//        UserVo user = (UserVo) respMsgBean.getData();
//        //添加角色和权限
//        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//        for (RoleVo role : user.getRoles()) {
//            //添加角色
//            simpleAuthorizationInfo.addRole(role.getRoleName());
//            for (PermissionVo permission:role.getPermissions()) {
//                //添加权限
//                simpleAuthorizationInfo.addStringPermission(permission.getPermissionName());
//            }
//        }
//        return simpleAuthorizationInfo;

        System.out.println("————权限认证————");
        String name = (String) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获得该用户角色
        UserVo user = checkUserFromRedis(name);
        List<RoleVo> roles = user.getRoles();
        Set<String> set = new HashSet<>();
        //需要将 role 封装到 Set 作为 info.setRoles() 的参数
        roles.forEach((role)->{set.add(role.getRoleName());});
        //设置该用户拥有的角色
        info.setRoles(set);
        return info;

    }


    public UserVo checkUserFromRedis(String name){
        UserVo user = null;
        Map<String,UserVo> onLineMap = new HashMap<String, UserVo>();
        if(!redisClient.hasKeyOfMap("onLineMap",name)){
            RespMsgBean<UserVo> respMsgBean = userClientService.findByName(name);
            user = respMsgBean.getData();
            // 设置缓存
            redisClient.setOneMap("onLineMap",name,user,60*60*24*7);
//            redisClient.setValue(name,user,60*60*24*7);
        }else{
//            user = (UserVo) redisClient.getValue(name);
            user = (UserVo) redisClient.getValueOfMap("onLineMap",name);
        }
        return user;
    }

}


4.编写shiro配置类,注入相应的bean,此类上一定要加@Configuration注解

/**
 * FileName: ShiroConfig
 * Date:     2018/12/5 15:00:00
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.XXXX.demo.shiro.config;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * 〈一句话功能简述〉<br>
 * shiro配置
 * @create 2018/12/5 15:00:00
 * @since 1.0.0
 */
@Configuration
public class ShiroConfig {

    /**
     * 将自己的验证方法注入容器
     * @prama
     * @return
     * @date 2018/12/5 15:28
     */
    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }


    /**
     * 权限管理,配置主要的realm的管理认证
     * @prama
     * @return
     * @date 2018/12/5 15:30
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    /**
     * Filter工厂,设置对应的过滤条件和跳转条件
     * @prama
     * @return
     * @date 2018/12/5 16:02
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 登录
        shiroFilterFactoryBean.setLoginUrl("/notLogin");
        // 设置无权限时跳转的 ur
        shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
        // 设置拦截器
        Map<String,String> map = new LinkedHashMap<String, String>();
        // 普通用户
        map.put("/user/**", "roles[user]");
        // admin
        map.put("/admin/**", "roles[admin]");
        // 开放登陆接口
        map.put("/login", "anon");
        // 登出
//        map.put("/logout","logout");
        // 对所有用户认证
        map.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        System.out.println("Shiro拦截器工厂类注入成功");
        return shiroFilterFactoryBean;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}


5.编写相应的控制类请求

/**
 * FileName: LoginController
 * Date:     2018/12/6 15:15:15
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.XXXX.demo.shiro.rest;

import com.XXXX.demo.client.redis.RedisClient;
import com.XXXX.demo.common.pojo.resp.RespMsgBean;
import com.XXXX.demo.shiro.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 〈一句话功能简述〉<br>
 * 测试shiro权限
 * @create 2018/12/6 15:15:15
 * @since 1.0.0
 */
@RestController
public class LoginController {

    @Resource
    private LoginService loginService;

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public RespMsgBean login(String name,String password){
        return new RespMsgBean().success(loginService.login(name,password));
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public RespMsgBean index(){
        return new RespMsgBean().success("登陆成功!");
    }

    @RequestMapping(value = "/notLogin", method = RequestMethod.GET)
    public RespMsgBean notLogin() {
        return new RespMsgBean().success("您尚未登陆!");
    }

    @RequestMapping(value = "/notRole", method = RequestMethod.GET)
    public RespMsgBean notRole() {
        return new RespMsgBean().success("您没有权限!");
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public RespMsgBean logout() {
        return new RespMsgBean().success(loginService.logout());
    }
}


 

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认收货,评价等一系列操作。 作为模拟天猫商城系统的核心组成部分之一,采用SSM框架的天猫数据管理后台包含商品管理,订单管理,类别管理,用户管理和交易额统计等模块,实现了对整个商城的一站式管理和维护。本课程是一门专业的Java微服架构开发实战课程,主要讲解了当下流行的SpringBoot框架、SpringCloud架构以及与第三方技术整合开发实战内容。通过本课程的学习,能够理解并掌握SpringBoot的基础知识,同时能够掌握SpringBoot与常用的第三方技术整合实现实际开发中的业务需求,包括实现Web开发、数据访问、缓存管理、安全管理、消息服务、任务管理等;了解并掌握SpringCloud微服务架构的基础知识及相关组件的应用,掌握微服务架构在企业级开发的实践,建立起微服架构思想。项目技术栈:采用SpringBoot简化商城系统的初始搭建以及开发过程采用SpringMVC+Spring+IBatis完成项目的整合采用Mysql作为数据库存储,Druid配置数据库连接池采用SpringCloud+Netflix 微服务技术栈的实战开发使用Redis完成缓存的数据存储,搭建Redis搭建主从、哨兵、集群应用,保证Redis的高可用使用ElasticSearch全文检索系统进行商品数据搜索,使用ElasticSearch搭建搜索服务的高可用使用Ngnix实现页面动静分离与负载均衡的配置采用FastDFS文件储存系统文件存储,完成广告图片、商品图片的上传和存储系统使用采用CAS+shiro单点登录系统实现用户认证使用ECharts根据后台查询数据生成图表使用POI实现了商城盈利状况的Excel表格导出。商品的详情页使用Thymeleaf完成页面静态化,减少页面数据展示延迟项目中使用SpringBoot下的Aop + 自定义注解完成用户行为记录,日志采集后台管理系统使用Shiro实现登录验证和权限管理(超级管理员、管理员、产品编辑员)项目整合微信完成订单的支付使用Redission完成分布式锁,生成订单的编号使用SpringCloud Alibaba Seat完成下订单模块的分布式事务(新增订单表,库存减少,库存超卖设计)使用RabbitMQ 做消息队列,完成订单未支付自动取消和模块直接的解耦合使用Quartz任务调度,完成缓存的定时刷新,保证缓存的一致性使用本地消息表机制完成消息然队列RabbitMQ消息可靠性传输订单支付模块使用微信扫码支付,并设置订单超时自动取消通过Jquery实现前端校验,通过基于Hibernate的Valida注解实现后端的校验功能使用Base64编码对Json数据传输进行编码和解码项目使用RESTful设计风格实现资源的访问,实现前后端分离项目使用聚合数据第三方短信平台完成用户的登陆功能项目使用SpringBoot整合JavaMail完成邮件的发送项目使用SpringBoot整合Swagger2生成接口文档使用PostMan完成接口的测试项目的测试:SpringTest、dbunit、EasyMock使用Docker 进行应用的自动化打包和发布、自动化测试和持续集成、部署和调整其他应用使用 PowerDesigner,完成数据库的建模项目使用禅道进行BUG管理环境采用Maven实施多模块项目构建,采用Git进行项目版本管理 架构解读:  项目部分截图:              讲义部分截图:          

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值