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

登录页面:

LoginController:

@GetMapping
public ModelAndView toLogin() {
	// 跳转登录页面
	ModelAndView mv = new ModelAndView("login");
	return mv;
}


@PostMapping()
public ModelAndView login(User user, HttpServletRequest request) {

	ModelAndView mv = new ModelAndView();
    //得到subject
	Subject subject = SecurityUtils.getSubject();
		
	//创建用户名和MD5加密过的密码身份验证Token
	UsernamePasswordToken token = new UsernamePasswordToken(
				user.getUserName(), new Md5Hash(user.getPassword(),user.getUserName()).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;
	}

}

登录失败:

登录成功:

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;

tip:若有错误或者疑问,欢迎评论留言

上一节:spring整合shiro

猜你喜欢

转载自blog.csdn.net/qq_37936542/article/details/81609145
今日推荐