基于springboot配置shiro中realm的验证、授权方法

前提准备:在springboot中已经整合好了SSMS框架

验证

一、编写前端页面发送请求

注册界面<br>
		<form action="/user/register">   
			账号:<input type="text" name="account"><br>
			密码:<input type="text" name="password"><br>
			<input type="submit" value="注册">
		</form>

二、编写对应用户的pojo类

		public class User {
				private String account;
				private String password;
				private List<Role> roles;
				对应的getter和seter方法。。。
		}

三、在controller中编写对应的 register()方法

//测试shiro,注册
@RequestMapping("/register")
public String register(User user){
	System.out.println("注册账号"+user);
	//给密码加密,注意:这里的“MD5”为加密方式,1024为加密次数,这个在shiro的配置类中是要我们自己配置的
	user.setPassword(new SimpleHash("MD5", user.getPassword(), null, 1024).toString());
	//将注册的user存入数据库
	userService.addUser(user);   // 事先注入的userService这个类
	return "/html/login.html"; //注册后回到登入界面 
}	

UserDao接口(现在看可能有些懵,稍后有数据库的表的结构和对应的pojo类)
在这里插入图片描述
在这里插入图片描述

UserService接口
正这是userService类式在这里插入图片描述
UserServiceImpl类
在这里插入图片描述
在这里插入图片描述
整个思路是:前端根据发送数据account,password,根据form的action :/user/register,然后在controller中找到对应的register的方法,也就是@requestMapping为(“/register”)的,接着根据springmvc框架,通过反射自动封装成User对象,在这里我们对账号的密码进行加密操作,这里的加密方式和加密次数应该和shiro的配置类中realm的配置的保持一致。

数据库的表的结构
在这里插入图片描述
用户表
在这里插入图片描述
现在完成的功能是注册,成功后会跳转到登入界面,那么就下来就是重点验证和授权的配置了

四、登入的前端界面

登入界面<br>
<form action="/user/login">
	账号:<input type="text" name="account"><br>
	密码:<input type="text" name="password"><br>
	<input type="submit" value="登入">
</form>

五、controller中login方法

//测试shiro,登入
@RequestMapping("/login")
public String login(User user){
	System.out.println("登入账号"+user);
	//获取subject(门面对象)
	Subject currentUser=SecurityUtils.getSubject();
	if (!currentUser.isAuthenticated()) { //没有认证的话
		//获取token
		UsernamePasswordToken token=new UsernamePasswordToken(user.getAccount(),user.getPassword());
		try {
			currentUser.login(token);  //该方法会将token中的账号和密码发送给安全管理器,安全管理器又会交给realm,realm中会进行认证和授权
			System.out.println("认证成功"); 
			return "/html/main.html"; //登入成功要跳转到的界面
		} catch (Exception e) {
			System.out.println("认证失败");
			//此处应该有好几种异常,就不一 一解释了
		}
	}
	return "/html/login.html"; //登入失败继续回到登入界面
}

六 、realm类(需要程序员自己编写,然后在shiro的配置类中配置)

简单的看一个shiro的配置类把(realm的配置,其他配置暂时略。。。)

在这里插入图片描述
接下来编写realm类中验证

public class UserRealm extends AuthorizingRealm{
@Resource   //注入的类,之前的代码里有
private UserService userService;
//授权(暂时略,后面会说)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

	return null;
}

//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
	System.out.println("正在认证...");
	//获取account,根据该account取数据库中查找User
	String account=(String) token.getPrincipal();
	User user=new User(account,null);
	User user2=userService.selectUser(user);     //user2为从数据库中查询到的真实的账号和密码封装的类
	if (user2==null) {
		return null;
	}                                  //然后再将真的是账号密码信息提价给安全管理器,由他进行判断,若是和前端的数据一致,则验证成功
	SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user2.getAccount(),user2.getPassword(),getName());
	return info;
	
}

}
此时基于springboot的shiro的验证已经完成了

授权

授权分为角色授权和权限授权,一般来说,角色授权是粗粒度的,范围较大的,它一般用来规定哪些角色可以访问哪些界面,而权限授权是细粒度的,它指的是针对于对数据库的增删查改,要拥有的权限,拥有该特定的权限才能执行特定的方法。一句话:角色针对访问页面,权限针对方法!

1、shiro配置类中shiroFilter的配置

//配置shiro的过滤器
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager,RoleFilter filter){
	ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
	//配置安全管理器
	bean.setSecurityManager(securityManager);
	//配置登入界面
	bean.setLoginUrl("/html/login.html");
	//配置未授权的界面
	bean.setUnauthorizedUrl("/html/error.html");
	//引入自定义的过滤器
	Map<String,Filter> filterMap=new HashMap<>();
	filterMap.put("user_admin", filter);
	bean.setFilters(filterMap);
	
	//设置其他过滤选项
	Map<String, String> map=new HashMap<>();
	map.put("/user/show", "anon");  //匿名可以访问的,不需要经过验证
	map.put("/user/addUser", "anon");
	map.put("/user/register", "anon");
	map.put("/user/login", "anon");
	map.put("/html/register.html", "anon");
	map.put("/html/login.html", "anon");
	map.put("/druid/**", "anon");
	
		//配置角色的权限     配置了角色权限,那么安全管理器就会自动调用realm里面的授权的方法;
		map.put("/html/user.html", "authc,roles[user]");
		map.put("/html/admin.html", "authc,roles[admin]");
		map.put("/html/root.html", "authc,roles[root]");
		//配置一个界面可以多个角色访问
		map.put("/html/user.html", "authc,user_admin[user,admin]");
	
	map.put("/logout", "logout");  //注销
	
	map.put("/**", "authc");  	 //全都要验证
	bean.setFilterChainDefinitionMap(map);
	
	return bean;
}

2、realm中编写授权方法

public class UserRealm extends AuthorizingRealm{
@Resource
private UserService userService;

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	System.out.println("正在授权...");
	//获得账号
	String account=(String) principals.getPrimaryPrincipal();
	//根据账号查询对应的角色(多对多);
	User userRoles=userService.findRolesByAccount(account);
	System.out.println("该账号为:"+"---------------"+account);
	System.out.println("该账号的角色为:"+userRoles.getRoles());
	List<Role> roles=userRoles.getRoles();
	//用来装上面的角色的名字的set容器,遍历每一个角色
	Set<String> set=new HashSet<>();
	Set<String> permsSet=new HashSet<>();
	for (Role role : roles) {
		set.add(role.getRname());
		//接 从数据库中查询角色对应的权限,根据角色的id查询到该角色对应的权限
		String rid=role.getRid();
		Role rolePerms=userService.findPermsByRid(rid);
		System.out.println("该角色拥有的权限为:"+"---------"+rolePerms.getPerms());
		List<Perm> perms=rolePerms.getPerms();
		for (Perm perm : perms) {
			//遍历该角色拥有的每一个权限,然后装入权限的set集合中,最后返回给安全管理器
			permsSet.add(perm.getPname());
		}
	}
	
	SimpleAuthorizationInfo info =new SimpleAuthorizationInfo(set);  //该账号拥有的角色信息
	info.addStringPermissions(permsSet);   //该角色拥有的权限信息
	
	return info;
}

这里可能有些乱:我整理了一下,就是在shiro的配置类中关于设置权限那块只要写了roles[ ]** 的,那么他登入的时候就会自动调用realm中的授权的方法,然后通过pringcipals.getPrimaryPricipal( )方法获得登入账号的account,接着根据该account去数据库中查询到该用户,那么就能查询到该用户的角色,当然,一个用户可能有多个角色,比如:一个用户他可能既是管理员,又是超级管理员,所以我这里用的是List接收,然后拥有的角色装入到Set集合中提交给SimpleAuthorizationInfo,但是还没有完,因为还有权限设置这一部分,查询到角色后,再根据角色查询到每一个角色拥有的权限,在把每一个权限装入到另一个Set集合中通过addStringPermissions() 提交。这样,就查询到了每个登入用户的角色以及拥有的权限!**

下面编写一个简单的方式测试一下:

注意:这里的shiro的注解是要自己开启的,要在shiro的配置类中进行配置

在这里插入图片描述
我现在用一个角色为admin的用户登入一个,然后执行这个方法
在这里插入图片描述
输入登入的url
在这里插入图片描述
在这里插入图片描述
登入成功,开始测试,点击注销之前的那个测试权限的
在这里插入图片描述
结果控制台报错了,说我没有那个user:delete的权限
在这里插入图片描述
在这里插入图片描述
因为在这里我是用的管理员的账号登入的,而这个管理员我没有设置user:delete的权限,超级管理员才有user:delete的权限,接下来我再用超级管理员的身份进行登入
测试成功,看输出台:
在这里插入图片描述
为了方便大家理解,我再赋上一张数据库 账号表、角色表、权限表之间关系的图(大致是这样的)
在这里插入图片描述

以上就是基于springboot配置shiro的 验证、授权的的全部内容,谢谢各位看官!~
PS:第一次写博客,本人就是菜鸟中的菜鸟,很多地方明知道写的不好,但不知道要怎么写,望大家见谅 !希望向各位技术大牛学习,一起进步!留个联系方式吧,希望和大家多多交流  QQ : 827699764  ,有需要的我把全部代码发给你们

猜你喜欢

转载自blog.csdn.net/weixin_44178366/article/details/92407533