springboot之shiro

前言:本人是刚学习java后端不久,所以通过记录一下平时所学知识,方便日后的复习,如果有出错的地方,还望包含。

1、shiro是springboot集成的一个安全框架,使用非常简单,相对于ssm来说,对初学者想要尽快入手,提供了可能。

前端的登录界面,可以用自己的,只要做好和后端接口的连接就行。

想要使用shiro,首先要引入shiro的pom坐标

         <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>
<!--配置shiro和thymeleaf,从而使不同人看到不同的页面,管理不同的权限&ndash;&gt;-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

2、controller层对登录接口的管理

//可以同时输入两个路径,这两个路径都是指定了登录界面,需要用一个大括号括起来
    //这个时候我们执行登录这个方法,一定会进行到userRealm中进行登录的认证。
    @RequestMapping({"/login"})
    public String login(Model model,
                        String userName,
                        String userPassword, HttpSession session)
    {
        System.out.println("loginController执行了。");

        //1.获取Subject
        Subject subject = SecurityUtils.getSubject();

        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(userName,userPassword);
        //3.执行登录方法
        try {
            subject.login(token);
//            System.out.println(token.getUsername());
            //登录成功以后,将值存放在session中,在前端通过 [[${session.username}]] 进行调用显示。
            session.setAttribute("username",token.getUsername());
            model.addAttribute("name",userName);

            //登录成功
            //跳转到test.html
            return "redirect:/index";
        } catch (UnknownAccountException e) {
            //e.printStackTrace();
            //登录失败:用户名不存在
            model.addAttribute("msg", "用户名不存在");
            model.addAttribute("name",userName);
            return "login";   //返回登录页面
        }catch (IncorrectCredentialsException e) {
            //登录失败:密码错误
            model.addAttribute("msg", "密码错误");
            return "login";   //返回登录页面
             }
        }

注释,这个是后端的登录接口,当用户提交的时候,会被shiro拦截,对用户的身份进行认证,对角色的权限,进行审核。

3、在自己的包下,创建一个config的配置包,包中有两个类

     第一个userRealm类

package com.newbie.demo0502.config;//package com.newbie.demo0502.config;

import com.newbie.demo0502.entity.User;
import com.newbie.demo0502.service.impl.UserServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义Realm
 * @author lenovo
 *
 */
public class UserRealm extends AuthorizingRealm{

	@Autowired
	private UserServiceImpl userSerivce;
	/**
	 * 执行授权逻辑
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		System.out.println("执行授权逻辑");

		//给资源进行授权
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		//可以在这个从数据库中查找用户的授权信息,放入其中,就可以对不同用户的权限分配进行管理
		//添加资源的授权字符串

		//到数据库查询当前登录用户的授权字符串
		//获取当前登录用户
		Subject subject = SecurityUtils.getSubject();
		//通过这句话,获取当前的用户
		User user = (User)subject.getPrincipal();
		//通过登录的用户名,获取当前用户的的所有信息
		User dbUser=userSerivce.seleceUserByName(user.getUserName());
//		//通过这句话获取用户的权限信息getPerms
		info.addStringPermission(dbUser.getUserMessage());

		return info;
	}



	/**
	 * 执行认证逻辑
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
		System.out.println("执行认证逻辑");

		//编写shiro判断逻辑,判断用户名和密码
		//1.判断用户名
		UsernamePasswordToken token = (UsernamePasswordToken)auth;
		//通过用户名,获取当前用户所有的信息
		User user = userSerivce.seleceUserByName(token.getUsername());

		if(user==null){
			//用户名不存在
			return null;//shiro底层会抛出UnKnowAccountException
		}

		  //2.判断密码
		return new SimpleAuthenticationInfo(user,user.getUserPassword(),"");
	}

}

注释:这个是userRealm类,用户的登录的认证,和用户访问一些功能时候的授权,都是经过这里,用户的每次操作都会到这里进行权限上的判断,判断用户的角色是否有对应操作的权限。

如果想要移植到其他的项目中,需要对上面的代码进行一定的修改。

ShiroConfig
package com.newbie.demo0502.config;//package com.newbie.demo0502.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.IdentityHashMap;
import java.util.Map;

/**
 * Shiro的配置类
 * @author lenovo
 *
 */
@Configuration
public class ShiroConfig {

	/**
	 * 创建ShiroFilterFactoryBean
	 */
	@Bean
	public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

		//设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		//添加Shiro内置过滤器
		/**
		 * Shiro内置过滤器,可以实现权限相关的拦截器
		 *    常用的过滤器:
		 *       anon: 无需认证(登录)可以访问
		 *       authc: 必须认证才可以访问
		 *       user: 如果使用rememberMe的功能可以直接访问
		 *       perms: 该资源必须得到资源权限才可以访问
		 *       role: 该资源必须得到角色权限才可以访问
		 */
		Map<String,String> filterMap = new IdentityHashMap<>();
		//对静态资源进行放行
		filterMap.put("/images/**","anon");

		//设置不需要进行认证的
		filterMap.put("/login", "anon"); //登录页
		filterMap.put("/login1", "anon"); //登录页
//		filterMap.put("/index", "anon"); //后台首页
		filterMap.put("/signIn","anon"); //注册
		filterMap.put("/register","anon"); //注册
		filterMap.put("/welcome","anon"); //welcome页
		filterMap.put("/ajaxCheckUsername","anon"); //ajax判断方法,检验用户名和密码是否存在
		//注销就是一句话,太神奇了
		filterMap.put("/logout","logout");


		//user下全部进行拦截
		filterMap.put("/*","auth");
		filterMap.put("/seleceUserByName","authc");

		//授权过滤器
		//注意:当前授权拦截后,shiro会自动跳转到未授权页面
		//设置用户接口授权
		filterMap.put("/deleteUser", "perms[svip]");//需要有VIp授权的用户,才可以进入,

		filterMap.put("/updateUser", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertUser", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllUser", "perms[svip]");//这对权限的设置在userRealm中。
		//设置学生接口授权

		filterMap.put("/findAllStudent", "perms[普通用户]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllStudent", "perms[vip]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllStudent", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertStudent", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertStudent", "perms[vip]");//这对权限的设置在userRealm中。

		filterMap.put("/updateStudent", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/deleteStudent", "perms[svip]");//这对权限的设置在userRealm中。

		//设置老师接口授权
		filterMap.put("/findAllTeacher", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllTeacher", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertTeacher", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/updateTeacher", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/deleteTeacher", "perms[svip]");//这对权限的设置在userRealm中。

		//设置班级接口授权
		filterMap.put("/findAllClass", "perms[vip]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllClass", "perms[普通用户]");//这对权限的设置在userRealm中。

		filterMap.put("/findAllClass", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertClass", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertClass", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/updateClass", "perms[svip]");//这对权限的设置在userRealm中。


		filterMap.put("/seleceUserByName", "perms[svip]");//这对权限的设置在userRealm中。

		filterMap.put("/seleceUserByName", "perms[vip]");//这对权限的设置在userRealm中。

		filterMap.put("/insertStudent", "perms[svip]");//这对权限的设置在userRealm中。


		filterMap.put("/seleceUserByName", "perms[vip]");//这对权限的设置在userRealm中。

		filterMap.put("/seleceUserByName", "perms[普通用户]");//这对权限的设置在userRealm中。

		filterMap.put("/seleceUserByName", "perms[svip]");//这对权限的设置在userRealm中。



		filterMap.put("/*","authc"); //通用的配置在最后,省得之前的不匹配了。

		//修改调整的登录页面
		shiroFilterFactoryBean.setLoginUrl("/login1");
		//设置未授权提示页面
		shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");

		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);


		return shiroFilterFactoryBean;
	}

	/**
	 * 创建DefaultWebSecurityManager
	 */
	@Bean(name="securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		//关联realm
		securityManager.setRealm(userRealm);
		return securityManager;
	}

	/**
	 * 创建Realm
	 */
	@Bean(name="userRealm")
	public UserRealm getRealm(){
		return new UserRealm();
	}

	/**
	 * 配置ShiroDialect,用于thymeleaf和shiro标签配合使用,可以实现未授权功能隐藏
	 */
	@Bean
	public ShiroDialect getShiroDialect(){
		return new ShiroDialect();
	}
}

注释:这个类主要是对数据表的角色,进行一系列的授权,给不同的用户绑定不同的身份,再通过shiro的方言(可以自己查一下),可以实现前端基于不同登录者的身份,显示不同的前端页面。

因为这个权限授予的底层是IdentityHashMap集合,所以很多的授权,都是根据键值对进行匹配的。

感受:使用了框架以后,只需要这两个类,就可以实现不同用户,可以看到不同的前端(这个是使用了shiro方言的功能,需要导入shiro方言的坐标,加上前端使用一个简单的权限判定的标签),才可以实现前端,根据不同的权限进行前端页面的不同显示,总之非常的方便。

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>