过滤web请求
在spring中存在一个DelegatingFilterProxy,是一种特殊的Filter,主要任务就是将工作委托给Filter实现类
使用@EnableWebSecurity注解时引入FilterChainProxy
1 2 3 4 5 6 7 8 9 10 11 12
| @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) public Filter springSecurityFilterChain() throws Exception { boolean hasConfigurers = webSecurityConfigurers != null && !webSecurityConfigurers.isEmpty(); if (!hasConfigurers) { WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor .postProcess(new WebSecurityConfigurerAdapter() { }); webSecurity.apply(adapter); } return webSecurity.build(); }
|
可以使用WebApplicationInitializer的方式来配置DelegatingFilterProxy,其会自动为每个url注册springSecurityFilterChain过滤器(也就是DelegatingFilterProxy),添加一个ContextLoaderListener来载入WebSecurityConfig
1 2 3 4
| public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
|
DelegatingFilterProxy会拦截发往应用中的请求,并将请求委托给springSecurityFilterChain,springSecurityFilterChain本身是另一种特殊的Filter,可以连接任意一个或多个其他的Filter
1 2 3 4 5 6 7 8 9 10 11
| 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); }
|
配置Spring Security
使用@EnableWebSecurity注解来启用web安全功能,需要配置在实现了WebSecurityConfigurer或者继承WebSecurityConfigurerAdapter类的bean上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Configuration @EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("tom") .password("123456") .roles("ADMIN") .authorities("UPDATE"); } public void configure(WebSecurity web) throws Exception { } protected void configure(HttpSecurity http) throws Exception {
http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); } }
|
用户信息获取
首先来将第一个configure方法,来进行用户信息的获取
1 2 3 4 5 6 7
| protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); }
|
使用自定义的用户服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class CustomUserDetailsService implements UserDetailsService {
@Autowired private AdminDao adminDao;
@Transactional(readOnly = true) public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Admin user = adminDao.findByName(username); if (user == null) { throw new UsernameNotFoundException("Username not found"); } List<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); return new org.springframework.security.core.userdetails.User(user.getUser_name(), user.getPassword(),authorities); } }
|
详细样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| protected void configure(HttpSecurity http) throws Exception { http .formLogin() .loginPage("/login.html")
.usernameParameter("username") .passwordParameter("password") .loginProcessingUrl("/user/login") .defaultSuccessUrl("/index") .and() .logout().logoutUrl("/logout") .logoutSuccessUrl("/index") .and() .authorizeRequests() .antMatchers("/","/test/").permitAll() .antMatchers("/user").authenticated() .antMatchers("/admin/").hasAuthority("admin") .antMatchers("/teacher/").hasAnyAuthority("admin","teacher") .antMatchers("/super/").hasRole("admin") .antMatchers("/student/").hasAnyRole("admin","teacher","student") .antMatchers("/school/").access("hasRole('admin')") .antMatchers("/ss/").anonymous() .antMatchers("/supper/").denyAll() .antMatchers("/full/").fullyAuthenticated() .antMatchers("/ip/").hasIpAddress("127.0.0.1") .antMatchers("/reme/").rememberMe() .anyRequest().authenticated() .and() .requiresChannel().anyRequest().requiresSecure() .and() .rememberMe().tokenValiditySeconds(3600).key("zhang") .and() .csrf().disable() .exceptionHandling().accessDeniedPage("/unauth.html"); }
|