SpringSecurity框架(二)纯注解配置
1.在web容器中注册过滤器链/*** 通过继承AbstractSecurityWebApplicationInitializer类,* 该已经实现了springSecurityFilterChain的注册**/public class SpringSecurityInitConfig extends AbstractSecurityWebApplicationIni...
·
1.在web容器中注册过滤器链
/**
* 通过继承AbstractSecurityWebApplicationInitializer类,
* 该已经实现了springSecurityFilterChain的注册
*
*/
public class SpringSecurityInitConfig extends AbstractSecurityWebApplicationInitializer {
}
实现了springSecurityFilterChain注册的源码
public abstract class AbstractSecurityWebApplicationInitializer
implements WebApplicationInitializer {
private static final String SERVLET_CONTEXT_PREFIX = "org.springframework.web.servlet.FrameworkServlet.CONTEXT.";
public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
private final Class<?>[] configurationClasses;
//加载时候调用onStartup方法
public final void onStartup(ServletContext servletContext) throws ServletException {
beforeSpringSecurityFilterChain(servletContext);
if (this.configurationClasses != null) {
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
rootAppContext.register(this.configurationClasses);
servletContext.addListener(new ContextLoaderListener(rootAppContext));
}
if (enableHttpSessionEventPublisher()) {
servletContext.addListener(
"org.springframework.security.web.session.HttpSessionEventPublisher");
}
servletContext.setSessionTrackingModes(getSessionTrackingModes());
//调用添加过滤器链方法
insertSpringSecurityFilterChain(servletContext);
afterSpringSecurityFilterChain(servletContext);
}
private void insertSpringSecurityFilterChain(ServletContext servletContext) {
String filterName = DEFAULT_FILTER_NAME;
DelegatingFilterProxy springSecurityFilterChain = new DelegatingFilterProxy(
filterName);
String contextAttribute = getWebApplicationContextAttribute();
if (contextAttribute != null) {
springSecurityFilterChain.setContextAttribute(contextAttribute);
}
//调用注册过滤器链方法
registerFilter(servletContext, true, filterName, springSecurityFilterChain);
}
//注册过滤器链的方法
private final void registerFilter(ServletContext servletContext,
boolean insertBeforeOtherFilters, String filterName, Filter filter) {
Dynamic registration = servletContext.addFilter(filterName, filter);
if (registration == null) {
throw new IllegalStateException(
"Duplicate Filter registration for '" + filterName
+ "'. Check to ensure the Filter is only configured once.");
}
registration.setAsyncSupported(isAsyncSecuritySupported());
EnumSet<DispatcherType> dispatcherTypes = getSecurityDispatcherTypes();
registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters,
"/*");
}
2.springSecurity配置文件
Filter在web.xml中配置的只是一个代理,而真正起作用的Filter是作为Bean配置在Spring中的。web.xml中的代理依次调用这些Bean,就实现了对Web资源的保护,同时这些Filter作为Bean被Spring管理,所以实现AOP也很简单,一举两得啊。
package cn.it.travel.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import cn.it.travel.service.UserService;
/**
* 1.添加@EnableWebSecurity 创建过滤器执行链给spring容器管理 springSecurityFilterChain
* 2.继承WebSecurityConfigurerAdapter 目的是重写父类的配置方法 应用自己添加的配置
* 3.注解@EnableGlobalMethodSecurity 开启注解拦截方法的请求
* prePostEnabled 设置在请求方法之前拦截auth方法,进行权限校验
*
*/
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserService userService;
/**
* configure(AuthenticationManagerBuilder auth)方法是用于配置
* 权限验证登陆管理
* */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
/**
* 自定义配置验证的service类 : 目的是查询数据库读取所有的用户权限
* 采用密文验证 :passwordEncoder
* 加密方式为 :getBCryptPasswordEncoder()
*/
auth.userDetailsService(userService).passwordEncoder(getBCryptPasswordEncoder());
}
/**
* 将加密方式的配置对象送入容器
*/
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* configure(HttpSecurity http) 用于请求回调拦截的配置
* */
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//添加不需要认证的路径
.antMatchers("/login.jsp", "/login.do", "/css/**",
"/img/**", "/plugins/**").permitAll()
//任何请求需要认证
.anyRequest().authenticated()
//权限前缀不要给
//.anyRequest().hasRole("ACCESS")
//.anyRequest().hasAnyAuthority()
//.anyRequest().fullyAuthenticated()
//关闭csrf 关闭跨域的验证
.and().csrf().disable()
//自定义配置登陆页面
.formLogin().loginPage("/login.jsp")
//自定义登陆请求地址
.loginProcessingUrl("/login.do").
//验证成功的跳转页面
successForwardUrl("/index.jsp").
//验证失败的跳转路径
failureForwardUrl("/failer.jsp")
//退出的请求路径
.and().logout().logoutUrl("/logout.do").
//退出请求后销毁session
invalidateHttpSession(true).
//退出成功跳转的页面
logoutSuccessUrl("/login.jsp")
//权限不足跳转的路径
.and().exceptionHandling().accessDeniedPage("/accessDenied.jsp");
}
}
3 将配置springSecurity的配置类加载到spring容器中
public class AppConfig implements WebApplicationInitializer{
//2.1创建AnnotationConfigWebApplicationContext
AnnotationConfigWebApplicationContext springContext = new AnnotationConfigWebApplicationContext();
//2.2spring的配置类 springSecurity的配置类
springContext.register(SpringConfig.class,SpringSecurityConfig.class);
4.权限的使用
在业务层方法上通过注解@PreAuthorize,配置调用方法需要的权限:
@PreAuthorize(“hasAuthority(‘PRODUCT_LIST’)”)
/**
*
* 查询所有商品
* @PreAuthorize("hasAuthority('PRODUCT_LIST')")
* 配置调用该业务层方法需要的权限为:PRODUCT_LIST
* */
@PreAuthorize("hasAuthority('PRODUCT_LIST')")
@Transactional(propagation = Propagation.SUPPORTS ,readOnly = true)
public PageInfo findAllProduct(Integer pageNum,Integer pageSize){
PageHelper.startPage(pageNum, pageSize);
List<Product> products = productDao.findAllProduct();
PageInfo pageInfo = new PageInfo(products);
return pageInfo;
};
更多推荐
已为社区贡献3条内容
所有评论(0)