昨天去学了shiro的授权,没有添加太多功能
先配置shiro注解@RequiresAuthentication 验证用户是否登录,等同于方法subject.isAuthenticated() @RequiresUser 验证用户是否被记忆,user有两种含义: 一种是成功登录的(subject.isAuthenticated() 结果为true); 另外一种是被记忆的(subject.isRemembered()结果为true)。 @RequiresGuest 验证是否是一个guest的请求,与@RequiresUser完全相反。 换言之,RequiresUser == !RequiresGuest。 此时subject.getPrincipal() 结果为null. @RequiresRoles 例如:@RequiresRoles("aRoleName"); void someMethod(); 如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。 @RequiresPermissions 例如: @RequiresPermissions({"file:read", "write:aFile.txt"} ) void someMethod();开启shiro注解
配置在Shiroconfig中
@Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean @ConditionalOnMissingBean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; }在方法上添加注解
@RequiresPermissions("adminUser:update") @RequestMapping("/updateAdminUser") public ResultObj updateAdminUser(@RequestBody AdminUser user){ return adminUserService.updateAdminUser(user); }
像这样子添加
在realm中添加授权信息//用户授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { log.info("开始用户授权"); String accessToken = (String) principalCollection.getPrimaryPrincipal(); Integer id = Integer.valueOf(JwtUtils.getUserId(accessToken)); //创建返回的info SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //先去redis里找,找不到再去claims里找 //以上留空为redis做准备 Claims claims = JwtUtils.getClaimsFromToken(accessToken); Listpermissions = (List ) claims.get(Constant.JWT_PERMISSIONS_KEY); if(permissions != null){ info.addStringPermissions(permissions); } return info; }
在用户第一次登录获得token的时候吧权限封装进token里
@Override public ResultObj login(String username, String password) { AdminUser user = adminUserDao.login(username); int user_id = user.getId(); String user_password = user.getPassword(); //检查密码是否正确 boolean passwordFlag = PasswordUtils.matches(user.getSalt(), password, user_password); if (user_id == 0 || !passwordFlag) { return new ResultObj(Constant.ERROR, Constant.USERNAME_PASSWORD_ERROR, null); } if (!user.getAvailable()) { return new ResultObj(Constant.ERROR, Constant.ADMINUSER_NOT_AVAILABLE, null); } //到这里就算登录通过,生成accessToken Map一个注意点claims = new HashMap<>(); //这里要加权限信息 加载claim中 //留空 //获取该用户所有角色 List roles = adminRoleDao.getAllRolesByUserId(user_id); //用Set来去重用户所有权限 Set permissions = new HashSet<>(); for(AdminRole role : roles){ //查询用户所拥有的每个角色所拥有的权限 List permissionList = adminPermissionDao.getAllPermissionsByRoleId(role.getId()); for (AdminPermission permission : permissionList){ permissions.add(permission.getPercode()); } } //将set转成string List permissionsToClaims = new ArrayList (permissions); claims.put(Constant.JWT_PERMISSIONS_KEY, permissionsToClaims); claims.put(Constant.JWT_USER_NAME, user.getUsername()); //accessToken 中传入adminuser的id和claims String accessToken = JwtUtils.getAccessToken(String.valueOf(user_id), claims); //创建 refreshToken 存入redis //具体逻辑尚未实现 String refreshToken = JwtUtils.getRefreshToken(String.valueOf(user_id),claims); //输出登录ip(为功能升级做准备) String ip = WebUtils.getRequest().getRemoteAddr(); log.info("登录人" + username + "的IP为" + ip); return new ResultObj(Constant.OK, Constant.LOGIN_SUCCESS, accessToken); }
//不能注册成Bean不然springboot会先接手这个bean,然后原先的公共资源就不能访问了 //@Bean //public JwtFilter jwtFilter() { // return new JwtFilter(); //}
在配置自己的过滤器的时候不能采用注入的方式,因为如果你用了Bean注入,这个过滤器就交给shiro管理了,这样的话你的配置就会乱了,所有在shiroconfig中采用new的方式注入filter
将系统用户与角色的关系从多对一变成了多对多
原先在AdminUser表中写死了每个系统用户的角色
现在改成了一个系统用户可以拥有多个角色
从AdminUser中删除了role_id字段
添加了remark备注字段
抽离出来了一张admin_user_role字段
修改了查询用户的语句
给table组件加了一个很牛逼的功能SELECT u.id as id,u.username as username,u.nickname as nickname, u.available as available,u.remark as remark FROM `admin_user` as u left join admin_user_role as ur on u.id = ur.u_id and u.username like #{myUsername} and u.nickname like #{myNickname} and ur.r_id = #{role_id}
首先是因为我返回的available属性是bool,再表格里直接这样写就显示不出来,经过查阅文档发现这样子需要对数据进行formatter
但是我又不想对子组件写死太多的规则,我更希望我对这个表格二次封装的组件有更高的自由度,经过查阅相关资料后我成功的实现了
只要在父组件实现formatter,传给子组件交给子组件去调用就好了
代码如下
父组件格式化代码,要加一个回调让子组件还可以收到value
//表格数据格式化 formatUserForm(row, column, value, callback) { // console.log("start format"); // console.log(column) let returnval; if (column.property === "available") { if (value === true) { returnval = "可用"; } else { returnval = "不可用"; } } else { returnval = value; } // let res = ''; callback(returnval); },
子组件中检测有没有这个属性,如果有就采用父组件的格式化方法,没有就全部按照string 输出
还有好多东西要写,但是晚上学校断网,手机链热点老是抽风,明天再写
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)