搭建环境

导入依赖

父工程导入Shiro的依赖

        <!--shiro和spring整合--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.3.2</version></dependency><!--shiro核心包--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.3.2</version></dependency><!--shiro与redis整合--><dependency><groupId>org.crazycake</groupId><artifactId>shiro-redis</artifactId><version>3.0.0</version></dependency>

配置值对象

不需要存入redis太多的用户数据,和获取用户信息的返回对象一致即可,需要实现AuthCachePrincipali接口

配置未认证controller

为了在多个微服务中使用,配置公共的未登录认证未授权的Controller

@RestController
@CrossOrigin
public class ErrorController {//公共错误跳转@RequestMapping(value="autherror")public Result autherror(int code) {//未认证或者未授权return code ==1?new Result(ResultCode.UNAUTHENTICATED):new Result(ResultCode.UNAUTHORISE);}}

自定义realm授权

ihrm-common模块下创建公共的认证与授权realm,需要注意的是,此realm只处理授权数据即可,认证方法需要在登录模块中补全。

package com.ihrm.common.shiro.realm;import com.ihrm.domain.system.response.ProfileResult;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
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 java.util.Set;//公共的realm:获取安全数据,构造权限信息
public class IhrmRealm  extends AuthorizingRealm {public void setName(String name) {super.setName("ihrmRealm");}//授权方法protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//1.获取安全数据ProfileResult result = (ProfileResult)principalCollection.getPrimaryPrincipal();//2.获取权限信息Set<String> apisPerms = (Set<String>)result.getRoles().get("apis");//3.构造权限数据,返回值SimpleAuthorizationInfo info = new  SimpleAuthorizationInfo();info.setStringPermissions(apisPerms);return info;}//认证方法protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {return null;}
}

自定义会话管理器

之前的程序使用jwt的方式进行用户认证,前端发送后端的是请求头中的token。为了适配之前的程序,在shiro中需要更改sessionId的获取方式。很好解决,在shiro的会话管理中,可以轻松的使用请求头中的内容作为sessionid

package com.ihrm.common.shiro.session;import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;public class CustomSessionManager extends DefaultWebSessionManager {/*** 头信息中具有sessionid*      请求头:Authorization: sessionid** 指定sessionId的获取方式*/protected Serializable getSessionId(ServletRequest request, ServletResponse response) {//获取请求头Authorization中的数据String id = WebUtils.toHttp(request).getHeader("Authorization");if(StringUtils.isEmpty(id)) {//如果没有携带,生成新的sessionIdreturn super.getSessionId(request,response);}else{//请求头信息:bearer sessionidid = id.replaceAll("Bearer ","");//返回sessionId;request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "header");request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);return id;}}
}

用户认证

配置用户登录

    /*** 用户登录*  1.通过service根据mobile查询用户*  2.比较password*  3.生成jwt信息**/@RequestMapping(value="/login",method = RequestMethod.POST)public Result login(@RequestBody Map<String,String> loginMap) {String mobile = loginMap.get("mobile");String password = loginMap.get("password");try {//1.构造登录令牌 UsernamePasswordToken//加密密码password = new Md5Hash(password,mobile,3).toString();  //1.密码,盐,加密次数UsernamePasswordToken upToken = new UsernamePasswordToken(mobile,password);//2.获取subjectSubject subject = SecurityUtils.getSubject();//3.调用login方法,进入realm完成认证subject.login(upToken);//4.获取sessionIdString sessionId = (String)subject.getSession().getId();//5.构造返回结果return new Result(ResultCode.SUCCESS,sessionId);}catch (Exception e) {return new Result(ResultCode.MOBILEORPASSWORDERROR);}}

shiro认证

package com.ihrm.system.shiro.realm;import com.ihrm.common.shiro.realm.IhrmRealm;
import com.ihrm.domain.system.Permission;
import com.ihrm.domain.system.User;
import com.ihrm.domain.system.response.ProfileResult;
import com.ihrm.system.service.PermissionService;
import com.ihrm.system.service.UserService;
import org.apache.shiro.authc.*;
import org.springframework.beans.factory.annotation.Autowired;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class UserRealm extends IhrmRealm {@Autowiredprivate UserService userService;@Autowiredprivate PermissionService permissionService;//认证方法protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//1.获取用户的手机号和密码UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;String mobile = upToken.getUsername();String password = new String( upToken.getPassword());//2.根据手机号查询用户User user = userService.findByMobile(mobile);//3.判断用户是否存在,用户密码是否和输入密码一致if(user != null && user.getPassword().equals(password)) {//4.构造安全数据并返回(安全数据:用户基本数据,权限信息 profileResult)ProfileResult result = null;if("user".equals(user.getLevel())) {result = new ProfileResult(user);}else {Map map = new HashMap();if("coAdmin".equals(user.getLevel())) {map.put("enVisible","1");}List<Permission> list = permissionService.findAll(map);result = new ProfileResult(user,list);}//构造方法:安全数据,密码,realm域名SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(result,user.getPassword(),this.getName());return info;}//返回null,会抛出异常,标识用户名和密码不匹配return null;}
}

获取session数据

baseController中使用shiro从redis中获取认证数据

package com.ihrm.common.controller;import com.ihrm.domain.system.response.ProfileResult;
import io.jsonwebtoken.Claims;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.ModelAttribute;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class BaseController {protected HttpServletRequest request;protected HttpServletResponse response;protected String companyId;protected String companyName;//使用shiro获取@ModelAttributepublic void setResAnReq(HttpServletRequest request,HttpServletResponse response) {this.request = request;this.response = response;//获取session中的安全数据Subject subject = SecurityUtils.getSubject();//1.subject获取所有的安全数据集合PrincipalCollection principals = subject.getPrincipals();if(principals != null && !principals.isEmpty()){//2.获取安全数据ProfileResult result = (ProfileResult)principals.getPrimaryPrincipal();this.companyId = result.getCompanyId();this.companyName = result.getCompany();}}}

用户授权

在需要使用的接口上配置@RequiresPermissions(“API-USER-DELETE”)

配置

package com.ihrm.system;import com.ihrm.common.shiro.realm.IhrmRealm;
import com.ihrm.common.shiro.session.CustomSessionManager;
import com.ihrm.system.shiro.realm.UserRealm;
import org.apache.shiro.mgt.SecurityManager;
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.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;
import java.util.Map;@Configuration
public class ShiroConfiguration {//1.创建realm@Beanpublic IhrmRealm getRealm() {return new UserRealm();}//2.创建安全管理器@Beanpublic SecurityManager getSecurityManager(IhrmRealm realm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(realm);//将自定义的会话管理器注册到安全管理器中securityManager.setSessionManager(sessionManager());//将自定义的redis缓存管理器注册到安全管理器中securityManager.setCacheManager(cacheManager());return securityManager;}//3.配置shiro的过滤器工厂/*** 再web程序中,shiro进行权限控制全部是通过一组过滤器集合进行控制**/@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {//1.创建过滤器工厂ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();//2.设置安全管理器filterFactory.setSecurityManager(securityManager);//3.通用配置(跳转登录页面,未授权跳转的页面)filterFactory.setLoginUrl("/autherror?code=1");//跳转url地址filterFactory.setUnauthorizedUrl("/autherror?code=2");//未授权的url//4.设置过滤器集合Map<String,String> filterMap = new LinkedHashMap<>();//anon -- 匿名访问filterMap.put("/sys/login","anon");filterMap.put("/autherror","anon");//注册//authc -- 认证之后访问(登录)filterMap.put("/**","authc");//perms -- 具有某中权限 (使用注解配置授权)filterFactory.setFilterChainDefinitionMap(filterMap);return filterFactory;}@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private int port;/*** 1.redis的控制器,操作redis*/public RedisManager redisManager() {RedisManager redisManager = new RedisManager();redisManager.setHost(host);redisManager.setPort(port);return redisManager;}/*** 2.sessionDao*/public RedisSessionDAO redisSessionDAO() {RedisSessionDAO sessionDAO = new RedisSessionDAO();sessionDAO.setRedisManager(redisManager());return sessionDAO;}/*** 3.会话管理器*/public DefaultWebSessionManager sessionManager() {CustomSessionManager sessionManager = new CustomSessionManager();sessionManager.setSessionDAO(redisSessionDAO());//禁用cookiesessionManager.setSessionIdCookieEnabled(false);//禁用url重写   url;jsessionid=idsessionManager.setSessionIdUrlRewritingEnabled(false);return sessionManager;}/*** 4.缓存管理器*/public RedisCacheManager cacheManager() {RedisCacheManager redisCacheManager = new RedisCacheManager();redisCacheManager.setRedisManager(redisManager());return redisCacheManager;}//开启对shior注解的支持@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();advisor.setSecurityManager(securityManager);return advisor;}
}

源代码

链接:https://pan.baidu.com/s/1Q5bruAOpRRQ7NTwT-QttaA
提取码:p7xc
–来自百度网盘超级会员V3的分享

SaaS-HRM中的认证授权相关推荐

  1. 在AngularJS应用中实现认证授权

    在AngularJS应用中实现认证授权 在每一个严肃的应用中,认证和授权都是非常重要的一个部分.单页应用也不例外.应用并不会将所有的数据和功能都 暴露给所有的用户.用户需要通过认证和授权来查看应用的某 ...

  2. 【实战 Ids4】║ 在Swagger中调试认证授权中心

    回家的路上照顾好自己哟~ 大家好,老张已经顺利到家啦,闲的无事写两篇文章冒个泡吧,其实写的内容都是群友提出来的问题,简单的我会在群里直接提供思路,麻烦的我就写个文章说明一下吧,也是自己的一个记录作用, ...

  3. Spring Security中关于认证授权的配置

    以下为Spring Security在配置文件中配置系统使用内存中用户.密码.授权信息 <security:authentication-manager><security:auth ...

  4. 安全性测试之认证授权

    在web安全中,认证授权又是每个人都熟知的,就像我们都应该设置一个高强度的密码,以免被猜测破解,实际上还包括更多内容.   1. 权限 在很多系统如CRM,ERP,OA中都有权限管理,其中的目的一个是 ...

  5. 正在向icntv服务器认证授权信息,Spring-Security-OAuth2服务器之搭建认证授权服务器[一]...

    结构基础 基础框架:Spring Boot + Spring-Security-OAuth2 存储介质:Mysql + Redis 持久化方式:Spring-data-jpa 测试工具:Postman ...

  6. Shiro 认证授权详解

    1     权限管理 1.1用户身份认证 1.1.1  概念 身份认证,就是判断一个用户是否为合法用户的处理过程.最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该 ...

  7. HRM认证授权方案_新版

    目录 一.HRM认证授权方案 1.HRM认证方案分析 1.1 问题分析 1.2 解决方案 二.认证服务 1.认证服务搭建 2.认证服务集成Security+Oauth2+JWT 3.定义登录流程 3. ...

  8. ASP“.NET研究”.NET中的认证与授权

    用户认证 .net提供了3种用户认证的方式,分别是Windows,Forms,Passport.这几种形式的定义可以在网站根目录下Web.config中的authentication节点中看见.Win ...

  9. 开启docker中MongoDB的认证授权

    开启docker中MongoDB的认证授权 思路 开启MongoDB服务后,默认是没有权限验证的.直接通过IP加端口就可以远程访问数据库,并对数据库进行任意操作.下面介绍一下如何开启docker中Mo ...

最新文章

  1. EBS   常见的AD命令
  2. C++ explicit关键字
  3. 谈论源码_5,000名开发人员谈论他们的薪水
  4. excel中线性函数_Excel中特别有用的不常用函数之Indirect函数
  5. 【转】VC 多线程中控制界面控件的几种方法
  6. 「代码随想录」518. 零钱兑换 II 【动态规划】力扣详解!
  7. 小卡与质数2全网最简单思路 看不懂你来打我
  8. vue-$nextTick-等待页面渲染完毕的回调
  9. ios 模拟器沙盒_查看iOS模拟器应用的沙箱文件
  10. Spark Core项目实战(3) | 页面单跳转化率统计
  11. 国庆 -- 2. 拍婚纱照
  12. 四旋翼无人机学习第15节--PCB Editor简单绘制封装-手动绘制封装
  13. 计算机音乐乐谱再也没有,在古代.这类音乐作品只有文字记载.没有乐谱资料.既无法演奏.也无法演唱.(在“既无法演奏 前加上“在今天 )...
  14. SpringBoot再回首:SpringBoot之Servlet用法
  15. 自己实现的php加密解密函数结果纯字母和数字
  16. Benders Decomposition初认识
  17. ubuntu 内网机器访问外网
  18. caxa齿轮零件图_利用CAXA在CATIA中绘制渐开线齿轮
  19. 爬虫之爬取淘宝主题市场主要产品信息
  20. 互融云工业品电商系统开发整体解决方案 助力行业数字信息化发展

热门文章

  1. My Hundredth Page - 回文子串 - By Nicolas
  2. Django学习记录8
  3. [转载] 晓说——第19期:千年科举那些事——官场
  4. 等维递推GM(1,1)模型、无偏灰色模型
  5. 读aroundall的回复有感
  6. on conflict的用法
  7. 传奇版本添加npc修改增加npc方法以及配置参数教程
  8. RocketMQ4.X消息队列详细笔记
  9. 5款最流行的笔记软件全方位横测
  10. Revit二次开发_获取视图样式替换