一:实现普通用户的session共享
二.超管redis共享tocken
1.在第一步的RedisCacheManager类中多放入一个cache,取个别名就行,不用重新创建
Cache cache = caches.get(name); if (cache == null) { cache = new RedisCache(redisTemplate); caches.put(name, cache); //超管登录时使用,实际就是原来的cache caches.put("superTicket", cache); }
2.直接替换SuperAdminTicketUtils类就可以,下面详情可忽略------------【序列化、修改引用、不可忽略】
2.把SuperAdminTicketUtils类的static方法都删掉,引用这个类中static方法放入类都改一下引用方式如下:【要把这个类交给spring去管理,加个注解就就好】
@Component
public class SuperAdminTicketUtils{
------------------------------------------------------------------------
@Autowired private SuperAdminTicketUtils superAdminTicketUtils;
2.1:在SuperAdminTicketUtils中注入RedisCacheManager
@Autowired private RedisCacheManager redisCache ;
2.2:然后就可以得到cache实例进行相关的对象存取操作了【注意这里的user要实现序列化接口】
public String putTicket(AuthorizationUser user) { String ticket = getTicket(); Cache<Object, ConcurrentHashMap<String, AuthorizationUser>> cache = redisCache.getCache("superTicket"); ticketMap = cache.get("Super-Ticket:")==null?ticketMap:cache.get("Super-Ticket:"); ticketMap.put(ticket, user); cache.put("Super-Ticket:",ticketMap); return ticket; }
序列化:实现接口后鼠标放在类上alt+Enter就可以生成uid
public class AuthorizationUser implements Serializable { private static final long serialVersionUID = -5556165398740497973L;
三:超管登录密码加密
1.引入js文件夹到plugin
2.layout-superlogin.html中引入JS
<script class="custom-script" src="../../static/plugin/crypto-js/crypto-js.js" th:src="@{/plugin/crypto-js/crypto-js.js}"></script> <script class="custom-script" src="../../static/plugin/crypto-js/core.js" th:src="@{/plugin/crypto-js/core.js}"></script> <script class="custom-script" src="../../static/plugin/crypto-js/aes.js" th:src="@{/plugin/crypto-js/aes.js}"></script>
3.编写superlogin.js文件
var key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF"); //十六位十六进制数作为密钥 var iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412'); //十六位十六进制数作为密钥偏移量 //解密方法 function Decrypt(word) { var encryptedHexStr = CryptoJS.enc.Hex.parse(word); var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr); var decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } //加密方法 function Encrypt(word) { var srcs = CryptoJS.enc.Utf8.parse(word); var encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return encrypted.ciphertext.toString().toUpperCase(); } function superLogin(){ var passWord = $("#signin-superamdin-password").val(); if(passWord==null || passWord==""){ passWord =""; }else{ passWord = passWord.trim(); } var prefix = getTimeStr("prefix"); var suffix = getTimeStr("suffix"); passWord = prefix+passWord+suffix var aesPassWord = Encrypt(passWord); $("#submit-superamdin-password").val(aesPassWord); return true; } function getTimeStr(flag){ var myDate = new Date(); var year = myDate.getFullYear(); //获取完整的年份(4位,1970-????) var month = myDate.getMonth()+1; //获取当前月份(0-11,0代表1月) month = month > 9 ? month : "0"+month; var day = myDate.getDate(); //获取当前日(1-31) day = day > 9 ? day : "0"+day; var hours = myDate.getHours(); //获取当前小时数(0-23) hours = hours > 9 ? hours : "0"+hours; var minutes = myDate.getMinutes(); //获取当前分钟数(0-59) minutes = minutes > 9 ? minutes : "0"+minutes; var seconds = myDate.getSeconds(); //获取当前秒数(0-59) seconds = seconds > 9 ? seconds : "0"+seconds; if(flag=="prefix"){ return ""+year+month+day }else{ return ""+hours+minutes+seconds } }
3.1:替换html部分的form部分
4.可直接替换superloginController.java 详情如下
4.1:校验是否超时,获取时间差
public boolean checkLogionTime(String rangeTime){ String strDate = rangeTime; //注意:SimpleDateFormat构造函数的样式与strDate的样式必须相符 SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //加上时间 //必须捕获异常 Date date= null; try { date = simpleDateFormat.parse(strDate); } catch (ParseException e) { e.printStackTrace(); } long min = getDatePoor(new Date(),date); if(min>=loginTimeOut) { return false; }else{ return true; } } //计算时间差 差多少分钟 绝对值 public static long getDatePoor(Date endDate, Date loginDate) { long nd = 1000 * 24 * 60 * 60; long nh = 1000 * 60 * 60; long nm = 1000 * 60; // long ns = 1000; // 获得两个时间的毫秒时间差异 long diff = endDate.getTime() - loginDate.getTime(); // 计算差多少分钟 long min = diff % nd % nh / nm; return Math.abs(min); }
4.2:验证之前解密 直接加在原来的步骤中就好
public String login(ModelMap modal, String superAdminUsername, String superAdminPassword, HttpServletRequest request, HttpServletResponse response) { if (StringUtils.isNotBlank(superAdminUsername) && StringUtils.isNotBlank(superAdminPassword)) { try { String str = AesUtil.desEncrypt(superAdminPassword); superAdminPassword = str.substring(8, str.length() - 6); String rangeTime = str.substring(0,8)+str.substring(str.length()-6); boolean b = checkLogionTime(rangeTime); if(!b) { modal.put(ErrorConstants.ERROR_MESSAGE, ErrorConstants.ERROR_SUPERADMIN_003); return "views/superLoginPage"; } } catch (Exception e) { LOGGER.error("decrypt applicationMetadataId failed", e); } SuperAdmin superAdmin = new SuperAdmin(); superAdmin.setUsername(superAdminUsername.trim());
有个超时时间的设置在propertity中
# unit minutes super.login.timeOut=5
5.后台要引入一个解密的Java工具类,ErrorConstants中加一个错误提示信息
public final static String ERROR_SUPERADMIN_003 = "登陆超时,不安全的请求!"; // 判断登录请求超过一定时间为不安全请求
完事!
四:单点登录ticket验证地址变更
1.ShiroCasConfig中假如如下配置
@Value("${cas.server.url}") private String casServerUrl;
替换如下内容
//@Bean(name = LOGOUT_FILTER_NAME) public ExtendLogoutFilter getExtendLogoutFilter(IAuthorizationService authorizationService) { ExtendLogoutFilter extLogoutFilter = new ExtendLogoutFilter(); extLogoutFilter.setName(LOGOUT_FILTER_NAME); extLogoutFilter.setEnabled(true); extLogoutFilter.setAuthorizationService(authorizationService); extLogoutFilter.setRedirectUrl(casServerUrl + "/logout?service=" + shiroServerUrlPrefix); return extLogoutFilter; }
@Bean(name = SHIRO_FILTER_NAME)
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager,
IAuthorizationService authorizationService) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
String loginUrl = casServerUrl + "/login?service=" + shiroServerUrlPrefix + WebConstants.CAS_FILTER_URI;
shiroFilterFactoryBean.setLoginUrl(loginUrl);
完事!
以上代码有优化完整篇 点这里 可查看详情