【Shiro】SpringBoot整合Shiro

本文介绍Shiro框架在SpringBoot项目中的整合与应用,包括自定义Realm类实现认证与授权,配置ShiroFilter进行权限拦截,以及如何处理登录逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Shiro的核心API

Subject:用户主题(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:Shiro连接数据的桥梁

1、整合SpringBoot:

pom导入jar文件:shiro-spring

2、自定义Realm类

编写自己的Realm类,实现授权与认证逻辑,继承AuthorizingRealm

public class AuthRealm extends AuthorizingRealm {
    //  授权逻辑
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
       System.out.println("授权逻辑");
       // 给资源进行授权
       SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
       // 添加资源的授权字符串,实际从数据库拿到授权字符串
       info.addStringPermissions("edit");  // edit这个字符串必须与用户之前拦截权限时候配置的字符串一致
       // 到数据库查询当前登录用户的授权字符串
       // 获取当前登录用户
       Subject subject=SecurityUtils.getSubject();
       User user=subject.getPrincipal();  // 通过getPrincipal拿到的就是下边的认证登录逻辑中的返回时候的第一个参数user
       User dbUser=userService.findById(user.getId());
       // 往info中添加授权字符串
       info.addStringPermissions(dbUser.getPerms());  // perms是用户表中的一列授权字段
       return info;
    }

    // 认证登录逻辑
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   		System.out.println("认证登录逻辑");
	    // 编写验证的逻辑,判断用户名和密码是否正确
	    // 1.判断用户名,实际都是从数据库获取用户的数据
	    // String name="wbs";
	    // String password="000";
	    UsernamePasswordToken token=(UsernamePasswordToken )token;
	    User user=userService.findUserByName(token.getUsername());
	    if(!token.getUsername.equals(name)){
	    	// 用户名不存在
	    	return null;  // 会抛出UnknownAccountException 
	    } 
       	// SimpleAuthorizationInfo是AuthenticationInfo 的一个子类
       	return new SimpleAuthorizationInfo(user,password,"");
    }
}

3、编写shiro配置类(关键步骤)

必须的三个步骤:
1、创建ShiroFilterFactoryBean
2、创建DefaultWebSecurityManager
3、创建Realm
下边是最基本的配置,也是必须的配置

@Configuration
public class ShiroConfiguration {
	// 创建ShiroFilterFactoryBean
    @Bean("shiroFilterFactoryBean ")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager")SecurityManager manager) {
		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		// 设置安全管理器
        bean.setSecurityManager(manager);
        /****************添加自己的认证开始****************/
	        // 添加Shiro内置过滤器
	        // Shiro内置过滤器,可以实现权限相关的拦截器
	        // 常用的过滤器:
	        	/*
	        	anon:无需认证(登录),即可访问
	        	authc:必须认证才可以访问
	        	user:如果使用rememberMeMe的功能直接可以访问
	        	perms:该资源必须授予资源权限才可以访问
	        	role:该资源必须得到角色权限才可以访问
	        	*/
	        	LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
	        	filterChainDefinitionMap.put("/add", "authc");
		        filterChainDefinitionMap.put("/index", "authc");
		        filterChainDefinitionMap.put("/login", "anon");  // login无需验证
		        filterChainDefinitionMap.put("/user/*","authc");  // 使用通配符,让user下边的所有资源都进行认证
		        // 授权过滤器
		        // 当前授权拦截后,Shiro会自动跳转到一个未授权页面,但是这个页面需要自己编写
		        filterChainDefinitionMap.put("/edit", "perms[edit]");
		        filterChainDefinitionMap.put("/update", "perms[update]");
		        // 修改跳转的登录页面
		        bean.setLoginUrl("/login");  //登录的时候,转向login这个controller,返回某个页面
		        bean.setSuccessUrl("/index");  // 登录成功,转向index这个controller,返回某个页面
     		    bean.setUnauthorizedUrl("/unauthorized");  // 设置未授权提示页面,转向unauthorized这个controller,返回某个页面
     		    bean.setFilterChainDefinitionMap(filterChainDefinitionMap);   // 将自己定义的需要拦截的都加入到拦截器链中
        /****************添加自己的认证结束****************/
        return bean;
        
    }
	// 创建DefaultWebSecurityManager
   @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm ) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        // 关联Realm
        manager.setRealm(authRealm);
        return manager;
    }
	// 创建Realm
    @Bean("authRealm")
    public AuthRealm authRealm(CredentialMatcher matcher) {
        return  new AuthRealm ();
    }
    /*
    配置ShiroDialect,用于thymeleaf和shiro的整合
    */
    @Bean
    public ShiroDialect getShiroDialect(){
    	return new ShiroDialect();
    }
    
}

4、登录逻辑处理

使用Shiro编写认证操作

@RequestMapping("/login")
    public String login(String name,String password,Model model) {
    	// 1.获取subject
        Subject subject = SecurityUtils.getSubject();
        // 2.接收用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        // 3.执行登录方法
        try {
        // 没有异常,代表登录成功
            subject.login(token);
            User user = (User) subject.getPrincipal();
            session.setAttribute("user", user);
            return "index";
        } catch (UnknownAccountException e) {
        // 用户名不存在 登录失败
        	model.addAttribute("msg","用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e) {
        // 密码错误 登录失败
        	model.addAttribute("msg","密码错误");
            return "login";
        }
        return "login";
    }

上边基本的程序代码,就是Shiro整合spring,进行简单的权限拦截功能,其中的Service、Controller、Mapper、Domain等实体类自己进行编写,如果是SpringMVC项目,可以参考SpringMVC,这个里面已经配置好了基本的SpringMVC的基本需要的所有配置,可以在这个项目的基础上边进行修改。

thymeleaf和Shiro标签配合使用的过程

1、在pon.xml中导入thymeleaf对Shiro的扩展坐标:thymeleaf-extras-shiro
2、配置ShiroDialect:在上边的ShiroConfig中代码中进行配置getShiroDialect这个方法

前端页面中写法如下:

<div shiro:hasPermission="edit">
	进入用户编辑页面
</div>
<div shiro:hasPermission="update">
	进入用户更新页面
</div>
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值