springboot+shiro入门学习(二)

上一篇简单学习了一下shiro。这篇我们整合springboot和shiro

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.shiro</groupId>
	<artifactId>shiro</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>springFreemarker-1</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!-- <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency> -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- shiro相关jar -->
	    <dependency>
	      <groupId>org.apache.shiro</groupId>
	      <artifactId>shiro-core</artifactId>
	      <version>1.2.1</version>
	    </dependency>
	    <dependency>
	      <groupId>org.apache.shiro</groupId>
	      <artifactId>shiro-web</artifactId>
	      <version>1.2.1</version>
	    </dependency>
	    <dependency>
	      <groupId>org.apache.shiro</groupId>
	      <artifactId>shiro-ehcache</artifactId>
	      <version>1.2.1</version>
	    </dependency>
	    <dependency>
	      <groupId>org.apache.shiro</groupId>
	      <artifactId>shiro-spring</artifactId>
	      <version>1.2.1</version>
	    </dependency>
	    
	    <!-- https://mvnrepository.com/artifact/junit/junit -->
		<dependency>
		    <groupId>junit</groupId>
		    <artifactId>junit</artifactId>
		    <version>4.12</version>
		    <scope>test</scope>
		</dependency>
	    
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

shiro配置类

/**
 * 
 */
package shiro.config;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
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;
import org.springframework.context.annotation.DependsOn;

import shiro.realm.MyRealm;

/**
 * @author JXQ
 * shiro配置类
 */
@Configuration
public class ShiroConfig {

	
	/**
	   *  核心的安全事务管理器
	 * @return
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myRealm());
		
		return securityManager;
	}
	
	/**
	   *   注入自定义的realm
	 * @return
	 */
	@Bean
	public MyRealm myRealm() {
		MyRealm realm = new MyRealm();
		realm.setCredentialsMatcher(hashedCredentialsMatcher());
		return realm;
	}
	
	@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		
		//设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		
		//默认跳转到登陆页面
        //shiroFilterFactoryBean.setLoginUrl("/login");
        //登陆成功后的页面
        //shiroFilterFactoryBean.setSuccessUrl("/index");
        //shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		
		Map<String,Filter> filterMap = new LinkedHashMap<>();
		shiroFilterFactoryBean.setFilters(filterMap);
		
		//权限控制map
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
	}
	
	/**
	   *  哈希密码比较器,在realm中作用参数使用
	   *  登陆时会比较用户输入的密码,跟数据库密码配合盐值salt解密后是否一致。
	 * @return
	 */
	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher macher = new HashedCredentialsMatcher();
		macher.setHashAlgorithmName("md5");
		macher.setHashIterations(1);
		return macher;
	}
	
	/**
	   * 开启shiro aop注解支持
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor advisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
	}
	
	
	/**
	 * Shiro生命周期处理器
	 * @return
	 */
	@Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }
	
	/**
            * 自动创建代理
     * @return
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}

自定义的Realm类:

/**
 * 
 */
package shiro.realm;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * @author JXQ
 *
 */
public class MyRealm extends AuthorizingRealm{

	Map<String, String> map = new HashMap<String, String>();
	
	{
		map.put("admin", "123456");
		super.setName("MyRealm");//这个名字可以随便取
	}
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//从主体传过来的认证信息中获取用户名
		String userName = (String)principals.getPrimaryPrincipal();
		
		//模拟从数据库获取角色和权限
		Set<String> roleSet = getRoleByUserName(userName);
		Set<String> permissionSet = getPermissinByUserName(userName);
		
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.addRoles(roleSet);
		authorizationInfo.addStringPermissions(permissionSet);
		return authorizationInfo;
	}


	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		
		//从主体传过来的认证信息中获取用户名
		String userName = (String)token.getPrincipal();
		
		//根据用户名获取密码,模拟从数据库获取
		//String password = getPassWord(userName);
		/*
		 * if(password == null) { return null; }
		 */
		Md5Hash password = new Md5Hash("123456", "TEST");
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, password,ByteSource.Util.bytes("TEST") ,"MyRealm");
		
		return simpleAuthenticationInfo;
	}

	private String getPassWord(String userName) {
		String password = map.get(userName);
		return password;
	}
	
	/**
	 * 从数据库获取角色
	 * @param userName
	 * @return
	 */
	private Set<String> getRoleByUserName(String userName) {
		Set<String> set = new HashSet<String>();
		set.add("admin");
		set.add("aaaaa");
		return set;
	}
	
	private Set<String> getPermissinByUserName(String userName) {
		Set<String> set = new HashSet<String>();
		set.add("user:delete");
		set.add("user:update");
		return set;
	}
}

Controller类:

/**
 * 
 */
package shiro.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author JXQ
 * 
 */
@RestController
@RequestMapping(value = "test")
public class TestController {
	
	@RequestMapping(value = "admin")
	@RequiresPermissions("user:delete")
	public String admin() {
		return "测试成功";
	}
	
	@RequestMapping(value = "login")
	public String login(String userName, String password) {
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
		subject.login(token);
		return "登录成功";
	}
}

在使用postman测试之前一定要先调用login。不然会出错。我们在set中设置了用户拥有user:delete权限和user:update权限

而访问admin方法需要user:delete权限。发现能够正确的访问。

修改访问admin方法需要的权限为:user:view

会发现报错信息为:

Not authorized to invoke method: public java.lang.String shiro.controller.TestController.admin()

其实这是没有配置没有权限时的访问路径。

shiro的自定义过滤器

package shiro.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

public class ShiroFilter extends AuthorizationFilter{

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o)
			throws Exception {
		
		Subject subject = getSubject(request, response);
		
		String[] roles = (String[])o;//需要的权限
		if(null == roles || roles.length == 0) {
			//说明不需要任何权限就可以访问
			return true;
		}
		for(String role : roles) {
			if(subject.hasRole(role)) {
				return true;
			}
		}
		return false;
	}

}

 修改shiroConfiguration文件:

@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		
		//设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		
		//默认跳转到登陆页面
        //shiroFilterFactoryBean.setLoginUrl("/login");
        //登陆成功后的页面
        //shiroFilterFactoryBean.setSuccessUrl("/index");
        //shiroFilterFactoryBean.setUnauthorizedUrl("/index.ftl");
		
		Map<String,Filter> filterMap = new LinkedHashMap<>();
		
		filterMap.put("url", new ShiroFilter());
		shiroFilterFactoryBean.setFilters(filterMap);
		
		//权限控制map
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        
        filterChainDefinitionMap.put("/test/admin", "url[admin,admin1]");
        //filterChainDefinitionMap.put("/test/admin", "url");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
	}

这个过滤器的意思是:当我们的admin方法访问需要的角色为admin或者admin1时,都可以访问这个方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值