SpringBoot入门学习(四) --- shiro安全框架,定时器,异步调用,全局日志

19 篇文章 0 订阅

shiro安全框架
控制登陆,角色权限管理,身份验证,授权,会话管理,web项目
导包

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>1.4.0</version>
		</dependency>

然后在src/main/resources下新建一个关于shiro的缓存配置文件ehcache-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="cacheManagerConfigFile">
<defaultCache  
          maxElementsInMemory="10000"  
          eternal="false"  
          timeToIdleSeconds="120"  
          timeToLiveSeconds="120"  
          overflowToDisk="false"  
          diskPersistent="false"  
          diskExpiryThreadIntervalSeconds="120"
          memoryStoreEvictionPolicy="LRU"/>
 <cache name="shiro-activeSessionCache" 
   eternal="false"  
        maxElementsInMemory="10000"    
        overflowToDisk="false"  
        timeToIdleSeconds="0"  
        timeToLiveSeconds="0"
        statistics="true"/>  
</ehcache>

新建一个Shiro的配置文件

package top.fuly.demo.config;

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

import javax.servlet.Filter;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
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.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import top.fuly.demo.realm.UserRealm;

@Configuration
public class ShiroConfiguration {
	/**
	 * ShiroFilterFactoryBean 处理拦截资源文件问题。
	 * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
	 * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager Filter Chain定义说明
	 * 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
	 * 3、部分过滤器可指定参数,如perms,roles
	 */
	@Bean
	public ShiroFilterFactoryBean shirFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

		// 必须设置 SecurityManager
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 拦截器.
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		// 配置静态资源允许访问
		filterChainDefinitionMap.put("/user/login**", "anon");  //anon可以直接被访问
		filterChainDefinitionMap.put("/user/loginAction*", "anon");  //anon可以直接被访问
		//filterChainDefinitionMap.put("/js/**", "anon");
		//filterChainDefinitionMap.put("/css/**", "anon");
		//filterChainDefinitionMap.put("/index", "anon");
		// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
		filterChainDefinitionMap.put("/**", "authc");   //授权才能访问
		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
		shiroFilterFactoryBean.setLoginUrl("/user/login"); //未授权页面自动跳转到login页面
		// 未授权界面;
		//shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		Map<String, Filter> filters = new HashMap<String, Filter>();
		shiroFilterFactoryBean.setFilters(filters);
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	@Bean
	public EhCacheManager getEhCacheManager() {
		EhCacheManager em = new EhCacheManager();
		em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
		return em;
	}

	// 开启Controller中的shiro注解
	@Bean
	public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
		daap.setProxyTargetClass(true);
		return daap;
	}

	/**
	 * 配置org.apache.shiro.web.session.mgt.DefaultWebSessionManager
	 * 
	 * @return
	 */
	@Bean
	public DefaultWebSessionManager getDefaultWebSessionManager() {
		DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
		defaultWebSessionManager.setSessionDAO(getMemorySessionDAO());
		defaultWebSessionManager.setGlobalSessionTimeout(4200000);
		defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
		defaultWebSessionManager.setSessionIdCookieEnabled(true);
		defaultWebSessionManager.setSessionIdCookie(getSimpleCookie());
		return defaultWebSessionManager;
	}

	/**
	 * 配置org.apache.shiro.session.mgt.eis.MemorySessionDAO
	 * 
	 * @return
	 */
	@Bean
	public MemorySessionDAO getMemorySessionDAO() {
		MemorySessionDAO memorySessionDAO = new MemorySessionDAO();
		memorySessionDAO.setSessionIdGenerator(javaUuidSessionIdGenerator());
		return memorySessionDAO;
	}

	@Bean
	public JavaUuidSessionIdGenerator javaUuidSessionIdGenerator() {
		return new JavaUuidSessionIdGenerator();
	}

	/**
	 * session自定义cookie名
	 * 
	 * @return
	 */
	@Bean
	public SimpleCookie getSimpleCookie() {
		SimpleCookie simpleCookie = new SimpleCookie();
		simpleCookie.setName("security.session.id");
		simpleCookie.setPath("/");
		return simpleCookie;
	}

	@Bean
	public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	@Bean(name = "securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
		DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
		dwsm.setRealm(userRealm);
		// <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->
		dwsm.setCacheManager(getEhCacheManager());
		dwsm.setSessionManager(getDefaultWebSessionManager());
		return dwsm;
	}

	@Bean
	public UserRealm userRealm(EhCacheManager cacheManager) {
		UserRealm userRealm = new UserRealm();
		userRealm.setCacheManager(cacheManager);
		return userRealm;
	}

	/**
	 * 开启shrio注解支持
	 * 
	 * @param userRealm
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(UserRealm userRealm) {
		AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
		aasa.setSecurityManager(getDefaultWebSecurityManager(userRealm));
		return aasa;
	}
}

这里是重点

    filterChainDefinitionMap.put("/user/login*", "anon");  //anon可以直接被访问
	filterChainDefinitionMap.put("/user/loginAction*", "anon");  //anon可以直接被访问
	// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
	filterChainDefinitionMap.put("/**", "authc");   //授权才能访问
	shiroFilterFactoryBean.setLoginUrl("/user/login"); //未授权页面自动跳转到login页面

要创建一个UserRealm类

package top.fuly.demo.realm;

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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.velocity.util.introspection.Info;

import fuly.FulyUtil;
import groovy.util.IFileNameFinder;

public class UserRealm extends AuthorizingRealm {

	private static final String String = null;
	private Object credentials;

	//控制角色权限
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	//控制登陆
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
		String username = at.getPrincipal().toString();
		
		if(username.contains("tom")){ //判断用户权限
			System.out.println(username +"   "+FulyUtil.getFileInfo());
			// return new SimpleAuthenticationInfo(username, "", "tom");
		}
		return new SimpleAuthenticationInfo("1", at, "realmName");
	}

}

测试

 @RequestMapping("/user/loginAction")
	 public String loginAction(String username){
		Subject subject =  SecurityUtils.getSubject();
		AuthenticationToken token  = new UsernamePasswordToken(username, "1234");
		try {
			subject.login(token);   //这里抛异常说明登陆失败
			return "login Success";
		} catch (Exception e) {
			return "login Fail ";
		}
	 }

在这边我没测出我想要的结果,但我知道了 shiro安全框架可以可以验证身份,可以验证角色.后续在实战项目中会详细用到这个的.

定时器
创建一个类,注入Spring容器

@Component
public class ScheduledTest {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 2000)
public void scheduled() {
System.out.println("码家学院提示你==》现在时间:" + dateFormat.format(new Date()));
}
}

在主函数上启动定时器

@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}

然后启动就完事了

SpringBoot异步调用Async
主函数加上@EnableAsync ,需要异步的方法上面加上@Async注解

@Component
public class AsyncDemo {
	@Async
	public void asyncTest1(){
		System.out.println(FulyUtil.getCurrentThreanName()+FulyUtil.getFileInfo());
	}
	@Async
	public void asyncTest2(){
		System.out.println(FulyUtil.getCurrentThreanName()+FulyUtil.getFileInfo());
	}
	@Async
	public void asyncTest3(){
		System.out.println(FulyUtil.getCurrentThreanName()+FulyUtil.getFileInfo());
	}
}
//FulyUtil.getCurrentThreanName()+FulyUtil.getFileInfo() 线程名称 和当前所在行

调用

	@RequestMapping("/hello")
	public String hello() {
		asyncDemo.asyncTest1();
		asyncDemo.asyncTest2();
		asyncDemo.asyncTest3();
		System.out.println(FulyUtil.getCurrentThreanName()+FulyUtil.getFileInfo());
		return "Hello Springboot";
	}

测试
在这里插入图片描述读取自定义配置参数
就是读取application.properties中我们自定义的参数
如在application.properties定义参数

name=tom

则在程序中读取应为(spring会将name的值自动注入用Value注解的地方)
@Value("${name}")
private String name;

全局日志
导包

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

创建一个Aspect类

package top.fuly.demo.Log;

import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class LogAspect {
	private Logger log = LoggerFactory.getLogger(getClass());
	
	@Pointcut("execution(public * top.fuly.demo.controller..*.*(..))")
	public void webLog() {
	}

	@Before("webLog()")
	public void doBefore(JoinPoint joinPoint) throws Throwable {
		// 接收到请求,记录请求内容
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		// 记录下请求内容
		log.info("URL : " + request.getRequestURL().toString());
		log.info("HTTP_METHOD : " + request.getMethod());
		log.info("IP : " + request.getRemoteAddr());
		Enumeration<String> enu = request.getParameterNames();
		while (enu.hasMoreElements()) {
			String name = (String) enu.nextElement();
			log.info("name:{},value:{}", name, request.getParameter(name));
		}
	}

	@AfterReturning(returning = "ret", pointcut = "webLog()")
	public void doAfterReturning(Object ret) throws Throwable {
		// 处理完请求,返回内容
		log.info("RESPONSE : " + ret);
	}
}

重点是:
@Pointcut(“execution(public * top.fuly.demo.controller….(…))”) 不要配置错误;
上面这段注解的意思如下:

  1. execution(): 表达式主体
  2. 第一个public *号:表示返回类型, *号表示所有的类型。
  3. 包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,top.fuly.demo.controller…包、子孙包下所有类的方法。
  4. 第二个*号:表示类名,*号表示所有的类。
  5. *(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数
    参考链接:https://www.cnblogs.com/30go/p/8443522.html
    运行起来测试:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值