当前位置: 代码迷 >> 综合 >> Springmvc+Shiro+zTree 实战(四):系统登录逻辑与实现授权
  详细解决方案

Springmvc+Shiro+zTree 实战(四):系统登录逻辑与实现授权

热度:12   发布时间:2023-11-30 19:49:10.0

登录页面:

 

LoginController:

@GetMapping
public ModelAndView toLogin() {// 跳转登录页面ModelAndView mv = new ModelAndView("login");return mv;
}@PostMapping()
public ModelAndView login(User user, HttpServletRequest request) {ModelAndView mv = new ModelAndView();//得到subjectSubject subject = SecurityUtils.getSubject();//创建用户名和MD5加密过的密码身份验证TokenUsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), new Md5Hash(user.getPassword()).toString());try {subject.login(token);// 登录,即用户身份认证} catch (AuthenticationException e) {// 登录失败,跳转登录页面log.error("用户登录失败", e);mv.addObject("msg", "用户名或密码错误");mv.setViewName("login");return mv;}if (subject.isAuthenticated()) {// 登录成功,保存用户信息,跳转首页request.getSession().setAttribute("user", user.getUserName());mv.setViewName("redirect:/user.do");return mv;} else {log.error("用户登录失败");mv.addObject("msg", "用户名或密码错误");mv.setViewName("login");return mv;}}

登录失败:

登录成功:

 

系统登出操作

上一节在xml配置了shiro登出过滤器,它的作用是在用户退出系统时,清空缓存等操作。解决更新用户权限后不立马起作用的小问题。

登出按钮如下,不需要写loginOut对应的Controller,shiro自动拦截,然后跳转登录界面,详见上一节配置

<li class="xxx"><a href="loginOut"> 退出 </a></li>

 

shiro授权常用方式一:基于注解

注解 意义 案例
@RequiresAuthentication 验证用户是否登录  
@RequiresUser 当前用户已经验证过了或则记住我了  
@RequiresGuest 是否是游客身份  
@RequiresRoles 判断subject中有aRoleName角色才可以访问方法someMethod @RequiresRoles({“admin”})
@RequiresPermissions 需要拥有权限 @RequiresPermissions({“file:read”, “write:aFile.txt”} )

 

Controller方法上面添加相应注解

@DeleteMapping(value="/{id}")
@ResponseBody
@RequiresRoles({"admin"})
public ResponseEntity<Integer> delUser(@PathVariable("id")int id) {try{userService.delUser(id);}catch(Exception e){log.error("删除用户失败",e);return new ResponseEntity<Integer>(HttpStatus.INTERNAL_SERVER_ERROR);}return new ResponseEntity<Integer>(Common.common_success,HttpStatus.OK);}

 

shiro授权常用方式二:jsp页面授权,基于<shiro>标签

导入<shiro>标签库:<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>

标签名称

标签条件(均是显示标签内容)

<shiro:authenticated>

登录之后

<shiro:notAuthenticated>

不在登录状态时

<shiro:guest>

用户在没有RememberMe时

<shiro:user>

用户在RememberMe时

<shiro:hasAnyRoles name="abc,123" >

在有abc或者123角色时

<shiro:hasRole name="abc">

拥有角色abc

<shiro:lacksRole name="abc">

没有角色abc

<shiro:hasPermission name="abc">

拥有权限资源abc

<shiro:lacksPermission name="abc">

没有abc权限资源

<shiro:principal>

显示用户身份名称

1:实现粗粒度权限控制,通过判断用户是否有角色/权限,控制左侧菜单栏的显示和隐藏

<shiro:hasPermission name="systemUser"><i class="fa fa-sitemap"></i> 用户中心					   <shiro:hasPermission name="userManager"><a href="user.do">用户管理</a></shiro:hasPermission> <shiro:hasPermission name="roleManager"><a href="role.do">角色管理</a></shiro:hasPermission>			
</shiro:hasPermission>

2:实现细粒度权限控制,通过判断用户是否有角色/权限,决定是否显示删除/编辑按钮

<shiro:hasPermission name="roleManagerDelete"><button id="del" onclick="del(${role.id})">删除</button>
</shiro:hasPermission>
<shiro:hasPermission name="roleManagerUpdate"><button id="upd" onclick="upd(${role.id})">修改</button>
</shiro:hasPermission>

 

注意1:调试过程中,可能会遇到自定义的DbRealm中授权方法进不去,这是因为,你在跳转的方法上面没有使用shiro授权注解,同时在要跳转的页面没有使用<shiro>标签授权。必须有授权行为,才能进入授权方法。

 

注意2:实践过程中,可能需要在js中拼接<shiro>标签,生成html代码,这是这样生成的<shiro>标签不起作用

例如:

var htm = '';
htm += '<shiro:hasPermission name="roleManagerDelete">';
htm += '<button>删除</button>';
htm += '</shiro:hasPermission>';
return htm;

解决思路:先在页面通过<shiro>标签生成一个变量,js根据这个变量来判断是否需要拼接删除按钮的html

<!-- jsp代码 -->
<shiro:hasPermission name="roleManagerDelete"><input type="text" id="isDelete" hidden="true" value="true">
</shiro:hasPermission><!-- js代码 -->
var htm = '';
if($("#isDelte").val() == "t"){htm += '<button>删除</button>';
}
return htm;

 

上一节:spring整合shiro

 

 

 

  相关解决方案