Security:权限管理

  • 常用权限拦截器

    • SecurityContextPersistenceFilter

      • 以前是HttpSesstionContextIntegrationFilter,位于过滤器的顶端,是第一个起作用的过滤器
      • 第一个用途:在执行其他过滤器之前,率先判断用户的session是否已经存在了一个spring security上下文的securityContext,如果存在,就把securityContext拿出来,放在securityContextHolder中,供security的其他部分使用。如果不存在,就创建一个securityContext出来,放在securityContextHolder中,供security的其他部分使用。
      • 第二个用途:在所有过滤器执行完毕后,清空securityContextHolder中的内容,因为securityContextHolder是基于ThreadLocal的,如果不清空,会受到服务器线程池机制的影响。
      • ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递。这样处理后,能够解决实际中的一些并发问题。ThreadLocalMap是ThreadLocal的一个内部类,是不对外使用的。当使用ThreadLocal存值时,首先获取到当前线程对象,然后获取到当前线程本地对象,本地变量map,最后将当前使用的所有local和传入的值放在map中。也就是说ThreadLocalMap中的key是ThreadLocal对象。这样,每个线程都对应一个本地的map,所以,一个线程可以存在多个线程本地变量。
      • ThreadLocal是解决线程并发问题的一个很好的思路,通过对每个线程提供一个独立的变量副本,解决线程并发访问变量的一个冲突问题
      • 当一个线程结束的时候,记得把ThreadLocal里的变量移除掉remove();
  • LogoutFilter
    • 只处理注销请求。在用户发送注销请求时,销毁用户的session,清空securityContextHolder,重定向到注销成功页面
  • AbstractAuthenticationProcessingFilter
    • 处理form登录的过滤器,与form登录有关的操作都在此进行。
  • DefaultLoginPageGeneratingFilter
    • 用来生成一个默认的登录页面,默认的访问地址为spring_security_login,这个登录页面虽然支持用户输入用户名密码,也支持remember me等功能,但是因为太难看了,只能在演示时做个样子,不能直接在实际项目中使用
  • BasicAutenticationFilter
    • 用来进行basic验证
  • SecurityContextHolderAwareRequestFilter
    • 用来包装客户的请求,目的是在原来请求的基础上,为后续程序提供一些额外的数据,比如getRomoteUser时,直接返回当前登录的用户名
  • RememberMeAuthenticationFilter
    • 实现Remember me功能,当用户cookie中存在remember me标记时,它会根据标记自动实现用户登录,并创建securityContext,授予对应的权限。spring security中的remember me依赖cookie实现,用户在登录时选择remember me,系统就会在登录成功后为用户生成一个唯一的标识,并将这个标识保存进cookie中,我们可以通过浏览器查看用户电脑中的cookie
  • AnonymousAutenticationFilter
    • 当用户没有登录时,默认为用户分配匿名用户的权限
  • ExceptionTranslationFilter
    • 处理filterSecurityInterceptor中抛出的异常,然后将请求重定向到对应页面,或返回应用的错误代码
  • SessionManagementFilter
    • 在用户登录成功之后,销毁用户的当前session,并重新生成一个session
  • filterSecurityInterceptor
    • 用户的权限控制都包含在这个过滤器中
    • 第一个功能,如果用户尚未登录,抛出尚未认证的异常
    • 第二个功能,如果用户已登录,但是没有访问当前资源的权限,会抛出拒绝访问的异常
    • 第三个功能,如果用户已登录,也具有访问当前资源的权限,那么放行
  • FilterChainProxy
    • 按照顺序调用一组filter,使他们既能完成验证授权的本职工作,又能相应spring Ioc的功能来很方便地得到其他依赖的资源
  • 将用户、权限、资源(url)采用数据库存储
  • 自定义过滤器,代替原有的 FilterSecurityInterceptor
  • 自定义实现 UserDetailsService、AccessDecisionManager和InvocationSecurityMetadataSourceService,并在配置文件进行相应的配置
  • 用户表(base_user)
code type length
ID varchar 32
USER_NAME varchar 50
USER_PASSWORD varchar 100
NIKE_NAME varchar 50
STATUS int 11
  • 用户角色表(base_user_role)

    code type length
    ID varchar 32
    USER_ID varchar 32
    ROLE_ID varchar 32
  • 角色表(base_role)

    code type length
    ID varchar 32
    ROLE_CODE varchar 32
    ROLE_NAME varchar 64
  • 角色菜单表(base_role_menu)

    code type length
    ID varchar 32
    ROLE_ID varchar 32
    MENU_ID varchar 32
  • 菜单表(base_menu)

    code type length
    ID varchar 32
    MENU_URL varchar 120
    MENU_SEQ varchar 120
    MENU_PARENT_ID varchar 32
    MENU_NAME varchar 50
    MENU_ICON varchar 20
    MENU_ORDER int 11
    IS_LEAF varchar 20

实现主要配置类

实现AbstractAuthenticationProcessingFilter

用于用户表单验证,内部调用了authenticationManager完成认证,根据认证结果执行successfulAuthentication或者unsuccessfulAuthentication,无论成功失败,一般的实现都是转发或者重定向等处理。

   @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
//获取表单中的用户名和密码
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
//组装成username+password形式的token
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
//交给内部的AuthenticationManager去认证,并返回认证信息
return this.getAuthenticationManager().authenticate(authRequest);
}

AuthenticationManager

AuthenticationManager是一个用来处理认证(Authentication)请求的接口。在其中只定义了一个方法authenticate(),该方法只接收一个代表认证请求的Authentication对象作为参数,如果认证成功,则会返回一个封装了当前用户权限等信息的Authentication对象进行返回。
Authentication authenticate(Authentication authentication) throws AuthenticationException;
在Spring Security中,AuthenticationManager的默认实现是ProviderManager,而且它不直接自己处理认证请求,而是委托给其所配置的AuthenticationProvider列表,然后会依次使用每一个AuthenticationProvider进行认证,如果有一个AuthenticationProvider认证后的结果不为null,则表示该AuthenticationProvider已经认证成功,之后的AuthenticationProvider将不再继续认证。然后直接以该AuthenticationProvider的认证结果作为ProviderManager的认证结果。如果所有的AuthenticationProvider的认证结果都为null,则表示认证失败,将抛出一个ProviderNotFoundException。
校验认证请求最常用的方法是根据请求的用户名加载对应的UserDetails,然后比对UserDetails的密码与认证请求的密码是否一致,一致则表示认证通过。
Spring Security内部的DaoAuthenticationProvider就是使用的这种方式。其内部使用UserDetailsService来负责加载UserDetails。在认证成功以后会使用加载的UserDetails来封装要返回的Authentication对象,加载的UserDetails对象是包含用户权限等信息的。认证成功返回的Authentication对象将会保存在当前的SecurityContext中。

实现UserDetailsService

UserDetailsService只定义了一个方法 loadUserByUsername,根据用户名可以查到用户并返回的方法。

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.debug("权限框架-加载用户");
List<GrantedAuthority> auths = new ArrayList<>(); BaseUser baseUser = new BaseUser();
baseUser.setUserName(username);
baseUser = baseUserService.selectOne(baseUser); if (baseUser == null) {
logger.debug("找不到该用户 用户名:{}", username);
throw new UsernameNotFoundException("找不到该用户!");
}
if(baseUser.getStatus()==2)
{
logger.debug("用户被禁用,无法登陆 用户名:{}", username);
throw new UsernameNotFoundException("用户被禁用!");
}
List<BaseRole> roles = baseRoleService.selectRolesByUserId(baseUser.getId());
if (roles != null) {
//设置角色名称
for (BaseRole role : roles) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getRoleCode());
auths.add(authority);
}
} return new org.springframework.security.core.userdetails.User(baseUser.getUserName(), baseUser.getUserPassword(), true, true, true, true, auths);
}

实现AbstractSecurityInterceptor

访问url时,会被AbstractSecurityInterceptor拦截器拦截,然后调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,再调用授权管理器AccessDecisionManager鉴权。

public class CustomSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
@Override
public void destroy() {
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
public void invoke(FilterInvocation fi) throws IOException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} catch (ServletException e) {
super.afterInvocation(token, null);
}
}
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return securityMetadataSource;
} public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
this.securityMetadataSource = securityMetadataSource;
}
}

FilterInvocationSecurityMetadataSource 获取所需权限

    @Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
//获取当前访问url
String url = ((FilterInvocation) object).getRequestUrl();
int firstQuestionMarkIndex = url.indexOf("?");
if (firstQuestionMarkIndex != -1) {
url = url.substring(0, firstQuestionMarkIndex);
}
List<ConfigAttribute> result = new ArrayList<>(); try {
//设置不拦截
if (propertySourceBean.getProperty("security.ignoring") != null) {
String[] paths = propertySourceBean.getProperty("security.ignoring").toString().split(",");
//判断是否符合规则
for (String path: paths) {
String temp = StringUtil.clearSpace(path);
if (matcher.match(temp, url)) {
return SecurityConfig.createList("ROLE_ANONYMOUS");
}
}
} //如果不是拦截列表里的, 默认需要ROLE_ANONYMOUS权限
if (!isIntercept(url)) {
return SecurityConfig.createList("ROLE_ANONYMOUS");
} //查询数据库url匹配的菜单
List<BaseMenu> menuList = baseMenuService.selectMenusByUrl(url);
if (menuList != null && menuList.size() > 0) {
for (BaseMenu menu : menuList) {
//查询拥有该菜单权限的角色列表
List<BaseRole> roles = baseRoleService.selectRolesByMenuId(menu.getId());
if (roles != null && roles.size() > 0) {
for (BaseRole role : roles) {
ConfigAttribute conf = new SecurityConfig(role.getRoleCode());
result.add(conf);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
} /**
* 判断是否需要过滤
* @param url
* @return
*/
public boolean isIntercept(String url) {
String[] filterPaths = propertySourceBean.getProperty("security.intercept").toString().split(",");
for (String filter: filterPaths) {
if (matcher.match(StringUtil.clearSpace(filter), url) & !matcher.match(indexUrl, url)) {
return true;
}
} return false;
}

AccessDecisionManager 鉴权

    @Override
public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
if (collection == null) {
return;
}
for (ConfigAttribute configAttribute : collection) {
String needRole = configAttribute.getAttribute();
for (GrantedAuthority ga : authentication.getAuthorities()) {
if (needRole.trim().equals(ga.getAuthority().trim()) || needRole.trim().equals("ROLE_ANONYMOUS")) {
return;
}
}
}
throw new AccessDeniedException("无权限!");
}

配置 WebSecurityConfigurerAdapter

/**
* spring-security配置
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired
private UserDetailsService userDetailsService; @Autowired
private PropertySource propertySourceBean; @Override
protected void configure(HttpSecurity http) throws Exception {
logger.debug("权限框架配置"); String[] paths = null;
//设置不拦截
if (propertySourceBean.getProperty("security.ignoring") != null) {
paths = propertySourceBean.getProperty("security.ignoring").toString().split(",");
paths = StringUtil.clearSpace(paths);
} //设置过滤器
http // 根据配置文件放行无需验证的url
.authorizeRequests().antMatchers(paths).permitAll()
.and()
.httpBasic()
// 配置验证异常处理
.authenticationEntryPoint(getCustomLoginAuthEntryPoint())
// 配置登陆过滤器
.and().addFilterAt(getCustomLoginFilter(), UsernamePasswordAuthenticationFilter.class)
// 配置 AbstractSecurityInterceptor
.addFilterAt(getCustomSecurityInterceptor(), FilterSecurityInterceptor.class)
// 登出成功处理
.logout().logoutSuccessHandler(getCustomLogoutSuccessHandler())
// 关闭csrf
.and().csrf().disable()
// 其他所有请求都需要验证
.authorizeRequests().anyRequest().authenticated()
// 配置登陆url, 登陆页面并无需验证
.and().formLogin().loginProcessingUrl("/login").loginPage("/login.ftl").permitAll()
// 登出
.and().logout().logoutUrl("/logout").permitAll(); logger.debug("配置忽略验证url"); } @Autowired
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getDaoAuthenticationProvider());
} /**
* spring security 配置
* @return
*/
@Bean
public CustomLoginAuthEntryPoint getCustomLoginAuthEntryPoint() {
return new CustomLoginAuthEntryPoint();
} /**
* 用户验证
* @return
*/
@Bean
public DaoAuthenticationProvider getDaoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setHideUserNotFoundExceptions(false);
provider.setPasswordEncoder(new BCryptPasswordEncoder());
return provider;
} /**
* 登陆
* @return
*/
@Bean
public CustomLoginFilter getCustomLoginFilter() {
CustomLoginFilter filter = new CustomLoginFilter();
try {
filter.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
filter.setAuthenticationSuccessHandler(getCustomLoginAuthSuccessHandler());
filter.setAuthenticationFailureHandler(new CustomLoginAuthFailureHandler()); return filter;
} @Bean
public CustomLoginAuthSuccessHandler getCustomLoginAuthSuccessHandler() {
CustomLoginAuthSuccessHandler handler = new CustomLoginAuthSuccessHandler();
if (propertySourceBean.getProperty("security.successUrl")!=null){
handler.setAuthSuccessUrl(propertySourceBean.getProperty("security.successUrl").toString());
}
return handler;
} /**
* 登出
* @return
*/
@Bean
public CustomLogoutSuccessHandler getCustomLogoutSuccessHandler() {
CustomLogoutSuccessHandler handler = new CustomLogoutSuccessHandler();
if (propertySourceBean.getProperty("security.logoutSuccessUrl")!=null){
handler.setLoginUrl(propertySourceBean.getProperty("security.logoutSuccessUrl").toString());
}
return handler;
} /**
* 过滤器
* @return
*/
@Bean
public CustomSecurityInterceptor getCustomSecurityInterceptor() {
CustomSecurityInterceptor interceptor = new CustomSecurityInterceptor();
interceptor.setAccessDecisionManager(new CustomAccessDecisionManager());
interceptor.setSecurityMetadataSource(getCustomMetadataSourceService());
try {
interceptor.setAuthenticationManager(this.authenticationManagerBean());
} catch (Exception e) {
e.printStackTrace();
}
return interceptor;
} @Bean
public CustomMetadataSourceService getCustomMetadataSourceService() {
CustomMetadataSourceService sourceService = new CustomMetadataSourceService();
if (propertySourceBean.getProperty("security.successUrl")!=null){
sourceService.setIndexUrl(propertySourceBean.getProperty("security.successUrl").toString());
}
return sourceService;
}
}

spring boot 拦截器、过滤器、监听器、定时器使用

一、application.java中配置

@EnableTransactionManagement

自动启用事务

@SpringBootApplication

@MapperScan(basePackages={"com.hxkj.waychat.dao"})

@ServletComponentScan

拦截器、过滤器、监听器的注解配置

二、监听器配置

package com.hxkj.waychat.intercept.listener;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

import javax.servlet.annotation.WebListener;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.hxkj.waychat.core.config.Constant;

import com.hxkj.waychat.core.utils.PropertiesUtils;

@WebListener

public class ThymeleafServletContextListener implements ServletContextListener {

private static Logger logger = LoggerFactory.getLogger(ThymeleafServletContextListener.class);

@Override

public void contextDestroyed(ServletContextEvent arg0) {

logger.info("----------:ServletContext销毁");

}

@Override

public void contextInitialized(ServletContextEvent arg0) {

logger.info("----------:ServletContext初始化");

logger.info("----------:baseUrl:"+PropertiesUtils.getPropertiesValue(Constant.BASE_URL)+";fileUrl:"+PropertiesUtils.getPropertiesValue(Constant.FILE_URL));

arg0.getServletContext().setAttribute("baseUrl", PropertiesUtils.getPropertiesValue(Constant.BASE_URL));

arg0.getServletContext().setAttribute("fileUrl", PropertiesUtils.getPropertiesValue(Constant.FILE_URL));

}

}

三、过滤器配置

package com.hxkj.waychat.intercept.fliter;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.annotation.WebFilter;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/*@WebFilter(filterName="MyFilter",urlPatterns="/*")*/

public class MyFilter implements Filter {

private static Logger logger = LoggerFactory.getLogger(MyFilter.class);

@Override

public void destroy() {

logger.info("----------:过滤器销毁");

}

@Override

public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)

throws IOException, ServletException {

logger.info("----------:过滤器执行内容");

arg2.doFilter(arg0, arg1);

}

@Override

public void init(FilterConfig arg0) throws ServletException {

logger.info("----------:过滤器初始化");

}

}

四、拦截器配置

1.spring boot拦截器默认有

HandlerInterceptorAdapter

AbstractHandlerMapping

UserRoleAuthorizationInterceptor

LocaleChangeInterceptor

ThemeChangeInterceptor

2.配置spring mvc的拦截器WebMvcConfigurerAdapter

public class WebAppConfig extends WebMvcConfigurerAdapter

3.实现添加拦截器方法

public void addInterceptors(InterceptorRegistry registry){

}

registry.addInterceptor可以通过此方法添加拦截器, 可以是spring提供的或者自己添加的

4.实例部分

public class WebAppConfig extends WebMvcConfigurerAdapter{

public static void main(String[] args) {

SpringApplication.run(WebAppConfig.class, args);

}

/**

* 配置拦截器

* @author lance

* @param registry

*/

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new UserSecurityInterceptor()).addPathPatterns("/user/**");

}

}

UserSecurityInterceptor代码

public class UserSecurityInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

return true;

}

@Override

public void postHandle(HttpServletRequest request,

HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest request,

HttpServletResponse response, Object handler, Exception ex)

throws Exception {

}

}

五、定时器使用

@Component

public class Scheduler {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Scheduled(cron="0 0/1 * * * ?") //每分钟执行一次

public void statusCheck() {

logger.info("每分钟执行一次。开始……");

//statusTask.healthCheck();

logger.info("每分钟执行一次。结束。");

}

@Scheduled(fixedRate=20000)

public void testTasks() {

logger.info("每20秒执行一次。开始……");

//statusTask.healthCheck();

logger.info("每20秒执行一次。结束。");

}

}

六、全局异常处理器使用

package com.hxkj.fsslr.controller;

import java.io.FileNotFoundException;

import javax.lang.model.type.UnknownTypeException;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

import com.hxkj.fsslr.core.utils.PageReturnUtils;

/**

* @ClassName: GlobalExceptionHandler

* @Description: 全局异常处理

* @author huzhihui_c@qq.com

* @date 2016年7月18日 下午1:17:59

*/

@ControllerAdvice

public class GlobalExceptionHandler {

private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(value=Exception.class)

@ResponseBody

public Object errorHandler(HttpServletRequest request,Exception e){

logger.info("-----捕获到异常-----");

//ajax请求异常返回

if(null != request.getHeader("X-Requested-With") && "XMLHttpRequest".equals( request.getHeader("X-Requested-With").toString())){

if (e instanceof NullPointerException) {

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "数据参数传入错误");

} else if (e instanceof FileNotFoundException) {

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "数据文件上传出错");

} else if (e instanceof ClassNotFoundException) {

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "系统未找到该jar包");

} else if (e instanceof UnknownTypeException) {

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "未知错误");

} else{

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, e.toString());

}

}

return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, e.toString());

}

}

一、application.java中配置 @EnableTransactionManagement 自动启用事务 @SpringBootApplication@MapperScan(basePackages={"com.hxkj.waychat.dao"}) @ServletComponentScan 拦截器、过滤器、监听器的注解配置 二、监听器配置 package com.hxkj.waychat.intercept.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.hxkj.waychat.core.config.Constant; import com.hxkj.waychat.core.utils.PropertiesUtils; @WebListenerpublicclass ThymeleafServletContextListener implements ServletContextListener { privatestatic Logger logger = LoggerFactory.getLogger(ThymeleafServletContextListener.class); @Overridepublic void contextDestroyed(ServletContextEvent arg0) { logger.info("----------:ServletContext销毁"); } @Overridepublic void contextInitialized(ServletContextEvent arg0) { logger.info("----------:ServletContext初始化"); logger.info("----------:baseUrl:"+PropertiesUtils.getPropertiesValue(Constant.BASE_URL)+";fileUrl:"+PropertiesUtils.getPropertiesValue(Constant.FILE_URL)); arg0.getServletContext().setAttribute("baseUrl", PropertiesUtils.getPropertiesValue(Constant.BASE_URL)); arg0.getServletContext().setAttribute("fileUrl", PropertiesUtils.getPropertiesValue(Constant.FILE_URL)); } } 三、过滤器配置 package com.hxkj.waychat.intercept.fliter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /*@WebFilter(filterName="MyFilter",urlPatterns="/*")*/publicclass MyFilter implements Filter { privatestatic Logger logger = LoggerFactory.getLogger(MyFilter.class); @Overridepublic void destroy() { logger.info("----------:过滤器销毁"); } @Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { logger.info("----------:过滤器执行内容"); arg2.doFilter(arg0, arg1); } @Overridepublic void init(FilterConfig arg0) throws ServletException { logger.info("----------:过滤器初始化"); } } 四、拦截器配置 1.spring boot拦截器默认有 HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationInterceptor LocaleChangeInterceptor ThemeChangeInterceptor 2.配置spring mvc的拦截器WebMvcConfigurerAdapter publicclass WebAppConfig extends WebMvcConfigurerAdapter 3.实现添加拦截器方法 public void addInterceptors(InterceptorRegistry registry){ } registry.addInterceptor可以通过此方法添加拦截器, 可以是spring提供的或者自己添加的 4.实例部分 publicclass WebAppConfig extends WebMvcConfigurerAdapter{ public static void main(String[] args) { SpringApplication.run(WebAppConfig.class, args); } /** * 配置拦截器 * @author lance * @param registry */public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new UserSecurityInterceptor()).addPathPatterns("/user/**"); } } UserSecurityInterceptor代码 publicclass UserSecurityInterceptor implements HandlerInterceptor { @Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { returntrue; } @Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } } 五、定时器使用 @Componentpublicclass Scheduler { privatefinal Logger logger = LoggerFactory.getLogger(this.getClass()); @Scheduled(cron="0 0/1 * * * ?") //每分钟执行一次 public void statusCheck() { logger.info("每分钟执行一次。开始……"); //statusTask.healthCheck(); logger.info("每分钟执行一次。结束。"); } @Scheduled(fixedRate=20000) public void testTasks() { logger.info("每20秒执行一次。开始……"); //statusTask.healthCheck(); logger.info("每20秒执行一次。结束。"); } } 六、全局异常处理器使用 package com.hxkj.fsslr.controller; import java.io.FileNotFoundException; import javax.lang.model.type.UnknownTypeException; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import com.hxkj.fsslr.core.utils.PageReturnUtils; /** * @ClassName: GlobalExceptionHandler * @Description: 全局异常处理 * @author huzhihui_c@qq.com * @date 2016年7月18日 下午1:17:59 */@ControllerAdvicepublicclass GlobalExceptionHandler { privatestatic Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ExceptionHandler(value=Exception.class) @ResponseBodypublic Object errorHandler(HttpServletRequest request,Exception e){ logger.info("-----捕获到异常-----"); //ajax请求异常返回if(null != request.getHeader("X-Requested-With") && "XMLHttpRequest".equals( request.getHeader("X-Requested-With").toString())){ if (e instanceof NullPointerException) { return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "数据参数传入错误"); } elseif (e instanceof FileNotFoundException) { return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "数据文件上传出错"); } elseif (e instanceof ClassNotFoundException) { return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "系统未找到该jar包"); } elseif (e instanceof UnknownTypeException) { return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, "未知错误"); } else{ return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, e.toString()); } } return PageReturnUtils.formatNormal("", PageReturnUtils.MSG_CODE_111111, PageReturnUtils.MSG_STATE_FALSE, e.toString()); } }

1.3Security:权限管理,过滤、监听、拦截的更多相关文章

  1. Html5 监听拦截Android返回键方法详解

    浏览器窗口有一个history对象,用来保存浏览历史. 如果当前窗口先后访问了三个网址,那么history对象就包括三项,history.length属性等于3. history对象提供了一系列方法, ...

  2. Curator源码阅读 - ConnectionState的管理与监听

    看看Curator框架 为实现对 连接状态ConnectionState的监听,都是怎么构造框架的.后面我们也可以应用到业务的各种监听中. Curator2.13实现 接口 Listener List ...

  3. RabbitMQ 入门系列:8、扩展内容:接收信息时:可否根据RoutingKey过滤监听信息,答案是不能。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  4. 数据权限管理中心 - 基于mybatis拦截器实现

    数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...

  5. 第34天学习打卡(GUI编程之组件和容器 frame panel 布局管理 事件监听 多个按钮共享一个事件 )

    GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 简介 GUi的核心技术:Swing AWT 1.界面不美观 2.需要jre环境 为什么要学习GU ...

  6. C#WinForm窗体监听/拦截操作动作

    C#中的事件也是通过封装系统消息来实现的,如果你在WndProc函数中不处理该消息 那么,它会被交给系统来处理该消息,系统便会通过代理来实现鼠标单击的处理函数,因此你可以通过 WndProc函数来拦截 ...

  7. android 电话监听和拦截

    一.首先在manifest.xml文件中获取监听电话权限,注册监听电话的Activity <receiver android:name=".PhoneReceiver"> ...

  8. SpringMVC拦截器(资源和权限管理)

    1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet.    DispatcherServle ...

  9. SpringMVC拦截器2(资源和权限管理)(作为补充说明)

    SpringMVC拦截器(资源和权限管理) 1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServle ...

随机推荐

  1. c实现双向链表

    实现双向链表:创建.插入.删除 #include <iostream> #include <stdio.h> #include <string.h> #includ ...

  2. css 计算值函数

    css有一些强大的函数: 1. calc 可以混合多种单位来计算 div { font-size: calc(100vw/5 + 1rem - 100px) } 2. max.min.clamp ma ...

  3. dosbox+masm汇编环境的安装和使用

    1. 下载dosbox安装程序:DOSBox0.74-win32-installer.exe 链接:https://pan.baidu.com/s/1gXPKTT-xKb6BpjOJdhmudA 密码 ...

  4. HDU 4393 Throw nails(贪心加模拟,追及问题)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=115361#problem/D 题意大致是:给出最多50000个人,拥有最初速度 ...

  5. 问题MySQL Error (2013): Lost connection to MySQL server at waiting for initial communication packet

    错误说明: SQL Error (2013): Lost connection to MySQL server at 'waiting for initial communication packet ...

  6. C++的精髓——代码复用、接口复用

    C++的精髓——代码复用.接口复用 在另一篇文章中提到C++三大特点的核心概括,也写在这里吧.封装:信息隐藏继承:代码复用多态:面向对象C++并不是面向对象,它包容多种编程思想,如面向过程,面向对象, ...

  7. 客户端配置代理服务实现yum上外网

    vi  /etc/profile http_proxy=http://172.20.188.193:3128/https_proxy=https://172.20.188.193:3128/expor ...

  8. PHP学习之分页类

    <?php $page = new Page(2, 40); var_dump($page->allUrl()); class Page { //每页显示多少条数据 protected $ ...

  9. Winform中利用委托实现窗体之间的传值

    点击打开按扭,打开传输值窗体 public partial class Form1 : Form { public Form1() { InitializeComponent(); } public ...

  10. android popupwindow 位置显示

    1.在控件的上方: private void showPopUp(View v) { LinearLayout layout = new LinearLayout(this); layout.setB ...