Springboot-Shiro-druid-mybatis

本文介绍Spring Boot集成Shiro进行权限管理。先阐述Shiro概念及主要功能,如认证、授权等;接着说明主要类,像Subject、SecurityManager等;然后讲解Shiro配置,包括通过Java代码配置及定义URL规则;最后给出具体示例代码及测试情况。

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

 

Springboot集成shiro

Shiro主要用来进行权限管理。简单的介绍如下:

一、概念

Shiro是一个安全框架,可以进行角色、权限管理。

Shiro主要功能如下:

  • Authentication(认证):用户身份识别,通常被称为用户“登录”
  • Authorization(授权):访问控制。比如某个用户是否具有某个操作的使用权限。
  • Session Management(会话管理):特定于用户的会话管理,甚至在非web 或 EJB 应用程序。
  • Cryptography(加密):在对数据源使用加密算法加密的同时,保证易于使用。


二、主要的类

  • 1.Subject:当前用户,Subject可以是一个人,也可以是第三方服务
  • 2.SecurityManager:管理所有Subject,可以配合内部安全组件 
  • 3.principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。
  • 4.credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。最常见的principals和credentials组合就是用户名/密码了。
  • 5.Realms:用于进行权限信息的验证,需要自己实现。
  • 6.Realm 本质上是一个特定的安全 DAO:它封装与数据源连接的细节,得到Shiro 所需的相关的数据。
  • 在配置 Shiro 的时候,你必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization)。
  • 我们需要实现Realms的Authentication 和 Authorization。其中 Authentication 是用来验证用户身份,Authorization 是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
  • 7.SimpleHash,可以通过特定算法(比如md5)配合盐值salt,对密码进行多次加密。

 三、Shiro配置

  • 1.Spring集成Shiro一般通过xml配置,SpringBoot集成Shiro一般通过java代码配合@Configuration和@Bean配置。
  • 2.Shiro的核心通过过滤器Filter实现。Shiro中的Filter是通过URL规则来进行过滤和权限校验,所以我们需要定义一系列关于URL的规则和访问权限。
  • 3.SpringBoot集成Shiro,我们需要写的主要是两个类,ShiroConfiguration类,还有继承了AuthorizingRealm的Realm类
  • ShiroConfiguration类,用来配置Shiro,注入各种Bean。

包括过滤器(shiroFilter)、安全事务管理器(SecurityManager)、密码凭证(CredentialsMatcher)、aop注解支持(authorizationAttributeSourceAdvisor)等等

Realm类,包括登陆认证(doGetAuthenticationInfo)、授权认证(doGetAuthorizationInfo)

四、具体示例如下:

ShiroConfig.java如下:

package com.shiro.demo.shiro;

import java.util.LinkedHashMap;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {
	
	@Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    	
		ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
    	filterFactoryBean.setSecurityManager(securityManager);
    	
    	LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
    	map.put("/login", "anon");
    	map.put("/loginUser", "anon");
        map.put("/druid/**", "anon");
        map.put("/shiro/logout", "logout");
        map.put("/user", "roles[user]");
        map.put("/admin", "roles[admin]");
        map.put("/edit", "perms[edit]");
        map.put("/**", "authc");
		
		filterFactoryBean.setLoginUrl("/login");
		filterFactoryBean.setSuccessUrl("/index");
		filterFactoryBean.setUnauthorizedUrl("/unauthorized");
		filterFactoryBean.setFilterChainDefinitionMap(map);
		return filterFactoryBean;
    }
	@Bean
	public SecurityManager securityManager(){
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        // 自定义session管理 使用redis
//        securityManager.setSessionManager(sessionManager());
        // 自定义缓存实现 使用redis
//        securityManager.setCacheManager(cacheManager());
        //缓存在内存
//        securityManager.setCacheManager(new MemoryConstrainedCacheManager());
        securityManager.setRealm(myShiroRealm());
        return securityManager;
	}
	
	@Bean
    public ShiroRealm myShiroRealm() {
        ShiroRealm shiroRealm = new ShiroRealm();
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }

	/**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了)
     * 
     */
	@Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
    	HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
    	credentialsMatcher.setHashAlgorithmName("MD5");
    	credentialsMatcher.setHashIterations(1024);
    	return credentialsMatcher;
    }
	/**
     * 开启shiro aop注解支持.
     * 使用代理方式;所以需要开启代码支持;
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
  //自动创建代理,没有这个鉴权可能会出错
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }
	
}

ShiroRealm.java:

package com.shiro.demo.shiro;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
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.util.ByteSource;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.shiro.demo.model.Permission;
import com.shiro.demo.model.Role;
import com.shiro.demo.model.User;
import com.shiro.demo.service.UserService;

public class ShiroRealm extends AuthorizingRealm{

	@Autowired
	private UserService userService;
	//授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		User user = (User) principals.fromRealm(getName()).iterator().next();
		List<String> permissionList = new ArrayList<>();
		List<String> roleNameList = new ArrayList<>();
		Set<Role> roles = user.getRoles();
		if(!CollectionUtils.isEmpty(roles)){
			for(Role role : roles){
				roleNameList.add(role.getRname());
				Set<Permission> permissionSet = role.getPermissions();
				if(!CollectionUtils.isEmpty(permissionSet)){
					for(Permission permission : permissionSet){
						permissionList.add(permission.getName());
					}
				}
			}
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(permissionList);
		info.addRoles(roleNameList);
		return info;
	}

	//认证登陆
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		String username = usernamePasswordToken.getUsername();
		User user = userService.findByUsername(username);
//		Object credentials = null;
//		if("admin".equals(username)){
//			credentials = "038bdaf98f2037b31f1e75b5b4c9b26e";
//		}else if("user".equals(username)){
//			credentials = "098d2c478e9c11555ce2823231e02ec1";
//		}
		//盐值
		ByteSource credentialsSalt = ByteSource.Util.bytes(username);
		return new SimpleAuthenticationInfo(user, user.getPassword(),credentialsSalt, getName());
	}

}

测试:

user用户:

admin用户:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值