SSSDJday7权限判断

权限判断
1.1.获取到所有权限进行判断
FilterChainDefinitionMapBuilder:
public class FilterChainDefinitionMapBuilder {

@Autowired
private IPermissionService permissionService;

public Map<String,String> createFilterChainDefinitionMap(){
   …
    filterChainDefinitionMap.put("/logout","logout"); //不登录也可以访问
    //从数据库拿到数据,放到咱们的Map中
    //1.拿到所有权限
    List<Permission> permissions = permissionService.findAll();
    //2.遍历权限,拿到权限与资源
    for (Permission permission : permissions) {
        String url = permission.getUrl();//资源
        String sn = permission.getSn();//权限
        //把路径与资源放到拦截中去
        filterChainDefinitionMap.put(url,"perms["+sn+"]");
    }
    filterChainDefinitionMap.put("/**","authc");

    return  filterChainDefinitionMap;

}

}

.拿到登录用户
之前咱们登录,是把用户放到shiro中进行管理,现在我们先把主体修改成Employee用户:
主体改成当前登录用户:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
Employee loginUser = employeeService.findByUsername(username);
if(loginUser==null){
return null;
}
//拿到登录用户的密码
String dbPassword = loginUser.getPassword();
//设置加盐
ByteSource salt = ByteSource.Util.bytes(“itsource”);
SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(loginUser,dbPassword,salt,getName());
return authorizationInfo;
}

修改页面展示:
主页面的用户现在变成了这个样子

修改代码:
shiro:user
欢迎[ <shiro:principal property=“username” />]登录,退出
</shiro:user>

2.2.2.UserContext:设置与拿到当前登录用户
public class UserContext {
private static final String USER_IN_SESSION = “loginUser”;
/**
* 把当前登录用户放入Session
/
public static void setUser(Employee loginUser) {
Subject subject = SecurityUtils.getSubject();
subject.getSession().setAttribute(USER_IN_SESSION, loginUser);
}
/
*
* 从Session中获取User
*/
public static Employee getUser() {
Subject subject = SecurityUtils.getSubject();
Employee curentUser = (Employee) subject.getSession().getAttribute(USER_IN_SESSION);
return curentUser;
}
}

2.2.3.LoginController:登录成功后把用户放到Session中

@RequestMapping(value="/login",method = RequestMethod.POST)
@ResponseBody
public JsonResult login(String username, String password){
//1.拿到访问的主体(当前登录用户)
Subject subject = SecurityUtils.getSubject();
//2.判断这个用户是否已经登录(通过验证)
if(!subject.isAuthenticated()){
….
}
//登录成功后,把当前登录用户放到session中
//1.拿到当前登录用户(这个主体就是当前登录用户)
Employee loginUser = (Employee) subject.getPrincipal();
//2.当前登录用户放到session中
UserContext.setUser(loginUser);
return new JsonResult();
}

2.2.4.根据用户id拿到权限
PermissionRepository
//根据当前登录用户拿到对应的权限
@Query(“select distinct p.sn from Employee e join e.roles r join r.permissions p where e.id = ?1”)
Set findSnByEmp(Long employeeId);

IPermissionService
Set findSnByEmp(Long employeeId);

PermissionServiceImpl
@Override
public Set findSnByEmp(Long employeeId) {
return permissionRepository.findSnByEmp(employeeId);
}

2.2.5.JpaRealm:进入权限判断

public class JpaRealm extends AuthorizingRealm {

@Autowired
private IEmployeeService employeeService;
@Autowired
private IPermissionService permissionService;

//AuthorizationInfo:授权(是否有权限进入操作)
// 我们只需要把相应的权限交给Shiro,它就会自动比对
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    //拿到主体信息(指的就是当前登录用户)
    Employee loginUser = UserContext.getUser();
    //获取权限资源(这里假设已经根据用户名到数据库中获取到了)
    Set<String> permissions = permissionService.findSnByEmp(loginUser.getId());
    //permissions.add("employee:index");
    //permissions.add("role:index");
    //permissions.add("employee:*");

    //拿到授权对象,并且所有权限交给它
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    simpleAuthorizationInfo.setStringPermissions(permissions);
    //返回授权对象
    return simpleAuthorizationInfo;
}


}

以上功能完成后,我们就可以测试咱们的用户是否有相应的权限!

2.3.权限判断Ajax请求
2.3.1.判断需知
现在,咱们进入一个页面进入判断已经能完成,但是如果是Ajax请求,如果返回的还是一个页面,用户的体验就非常的差,所以我们接下来要解决的是这个问题:

咱们所有的请求可以分为两大类,一个是跳转页面,xxx/index 还有一类是Ajax请求期望返回的是{“success”:false,”message”:”没有权限”}

区分处理是否是Ajax请求,普通跳转页面的请求 ,就跳转没有权限的页面,如果是ajax请求返回{“success”:false,”message”:”没有权限”}

?怎么Ajax 判断请求头里面是否有X-Requested-With
跳转页面请求头

Ajax请求多个一个请求头X-Requested-With XMLHttpRequest

2.3.2.自定义权限拦截器
区分处理–shiro默认的权限过滤器不支持,需要自定义过滤器才行

上面的配置会交给

自定义权限的功能:可以参考我们给大家准备Shiro的资料

ItsourceYxbPermissionsAuthorizationFilter:自定义权限过滤器
public class ItsourceYxbPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
    Subject subject = this.getSubject(request, response);
    if (subject.getPrincipal() == null) {
        //没有登录成功后的操作
        this.saveRequestAndRedirectToLogin(request, response);
    } else {
        //登录成功后没有权限的操作
        //1.转成http的请求与响应操作
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        //2.根据请求确定是什么请求
        String xRequestedWith = httpRequest.getHeader("X-Requested-With");
        if (xRequestedWith != null &&"XMLHttpRequest".equals(xRequestedWith)) {
            //3.在这里就代表是ajax请求
            //表示ajax请求 {"success":false,"message":"没有权限"}
            httpResponse.setContentType("text/json; charset=UTF-8");
            httpResponse.getWriter().print("{\"success\":false,\"msg\":\"没有权限\"}");
        }else {
            String unauthorizedUrl = this.getUnauthorizedUrl();
            if (StringUtils.hasText(unauthorizedUrl)) {
                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            } else {
                WebUtils.toHttp(response).sendError(401);
            }
        }
    }
    return false;
}

}
applicationContext-shiro.xml

FilterChainDefinitionMapBuilder
public Map<String,String> createFilterChainDefinitionMap(){

Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
//注:对于一些不登录也可以放行的设置(大家可以根据实际情况添加)
filterChainDefinitionMap.put("/login","anon");
filterChainDefinitionMap.put("*.js","anon");
filterChainDefinitionMap.put("*.css","anon");
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/easyui/**","anon");
filterChainDefinitionMap.put("/images/**","anon");

filterChainDefinitionMap.put("/logout","logout"); //不登录也可以访问
//这个值之后从数据库中查询到【用户-角色-权限-资源】
//从数据库拿到数据,放到咱们的Map中
//1.拿到所有权限
List<Permission> permissions = permissionService.findAll();
//2.遍历权限,拿到权限 资源
for (Permission permission : permissions) {
    String url = permission.getUrl();//资源
    String sn = permission.getSn();//权限
    //把路径与资源放到拦截中去
    filterChainDefinitionMap.put(url,"yxbPerms["+sn+"]");
}
filterChainDefinitionMap.put("/**","authc");
return  filterChainDefinitionMap;

}

3.菜单读取
用户->角色->权限->菜单
用户有哪些权限,就应该有对应的菜单
(这里咱们可以分析数据库理解设计)
用户拥有对应的权限就拥有对应的菜单(二级菜单),如果此菜单有父菜单(一级菜单)也同时拥有
3.1.Domain设计
3.1.1. Menu
@Entity
@Table(name=“menu”)
public class Menu extends BaseDomain {

 private String name;//菜单名称
 private String url; //路径
 private String icon; //图标

/**
 * JsonIgnore:生成JSON的时候忽略这个属性
 */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="parent_id")
@JsonIgnore //这里生成json的时候要忽略,否则会造成功能相互调用
private Menu parent;

/**
 * 还要配置一个一对多
 *  这个字段不要交给JPA管理【到时候自己写代码管理】
 *  数据库的menu表中就应该有一个children,而且还是List类型
 *  Transient:临时属性(JPA不管这个属性,和数据库没有关系)
 */
@Transient
private List<Menu> children = new ArrayList<>();

…

public String getText(){ //EasyUI的树需要一个text属性
return name;
}
}

3.1.2.Permission
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name=“menu_id”)
private Menu menu;

3.2.功能完成
3.2.1.MenuRepository
//根据用户名拿到一个人对应的所有子菜单
@Query(“select distinct m from Employee e join e.roles r join r.permissions p join p.menu m where e.id = ?1”)
List

findByLoginUser(Long userId);

3.2.2.MenuService
@Override
public List

findByLoginUser(Long userId) {
//准备父菜单容器
List parentMenus = new ArrayList<>();
//从数据库中拿到子菜单
List childrenMenus = menuRepository.findByLoginUser(userId);
//遍历子菜单(如果有父菜单放进入,没有单独创建)
for (Menu childrenMenu : childrenMenus) {
//拿到子菜单对应的父菜单
Menu parent = childrenMenu.getParent();
//判断如果父菜单中是否有这个菜单
if(parentMenus.contains(parent)){
//有的话,咱们就把子菜单放到父菜单中去
int i = parentMenus.indexOf(parent);
Menu parentMenu = parentMenus.get(i);
parentMenu.getChildren().add(childrenMenu);
}else{
//如果没有,再单独把父菜单放进去
parentMenus.add(parent);
parent.getChildren().add(childrenMenu);
}
}
return parentMenus;
}

3.2.3.UtilController
@RequestMapping("/loginUserMenus")
@ResponseBody
public List loginUserMenus(Long id){
Employee loginUser = UserContext.getUser();
return menuService.findByLoginUser(loginUser.getId());
}

最后把主页面查找菜单的路径替换成咱们现在的路径即可(效果如下【不同的人看到的不同】)

4.页面按钮权限控制
4.1.功能描述
一个用户如果有查看员工的权限,但是它却没有删除的权限,我们连按钮都不应该让他看到!

4.2.功能实现
<shiro:hasPermission name=“employee:save”>
添加
</shiro:hasPermission>
<shiro:hasPermission name=“employee:update”>
修改
</shiro:hasPermission>
<shiro:hasPermission name=“employee:delete”>
删除
</shiro:hasPermission>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
使用 JavaScript 编写的 Squareshooter 游戏及其源代码   项目:使用 JavaScript 编写的 Squareshooter 游戏(附源代码) 这款游戏是双人游戏。这是一款使用 JavaScript 编写的射击游戏,带有门户和强化道具。在这里,每个玩家都必须控制方形盒子(作为射手)。这款射击游戏的主要目标是射击对手玩家以求生存。当它射击对手时,它会获得一分。 游戏制作 该游戏仅使用 HTML 和 JavaScript 开发。该游戏的 PC 控制也很简单。 对于玩家 1: T:朝你上次动作的方向射击 A:向左移动 D:向右移动 W:向上移动 S:向下移动 对于玩家2: L:朝你上次移动的方向射击 左箭头:向左移动 右箭头:向右移动 向上箭头:向上移动 向下箭头:向下移动 游戏会一直进行,直到您成功射击对手或对手射击您为止。游戏得分显示在顶部。所有游戏功能均由 JavaScript 设置,而布局和其他次要功能则由 HTML 设置。 如何运行该项目? 要运行此项目,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox。要运行此游戏,首先,通过单击 index.html 文件在浏览器中打开项目。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值