package com.welampiot.security; import com.welampiot.service.impl.UserDetailsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.ObjectPostProcessor; 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.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.annotation.Resource; @Configuration @EnableWebSecurity//开启Spring Security的功能 //prePostEnabled属性决定Spring Security在接口前注解是否可用@PreAuthorize,@PostAuthorize等注解,设置为true,会拦截加了这些注解的接口 @EnableGlobalMethodSecurity(prePostEnabled=true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Resource private MD5PasswordEncoder md5PasswordEncoder; //登录成功处理逻辑 @Autowired CustomizeAuthenticationSuccessHandler authenticationSuccessHandler; //登录失败处理逻辑 @Autowired CustomizeAuthenticationFailureHandler authenticationFailureHandler; //权限拒绝处理逻辑 @Autowired CustomizeAccessDeniedHandler accessDeniedHandler; //匿名用户访问无权限资源时的异常 @Autowired CustomizeAuthenticationEntryPoint authenticationEntryPoint; //会话失效(账号被挤下线)处理逻辑 @Autowired CustomizeSessionInformationExpiredStrategy sessionInformationExpiredStrategy; //登出成功处理逻辑 @Autowired CustomizeLogoutSuccessHandler logoutSuccessHandler; //访问决策管理器 @Autowired CustomizeAccessDecisionManager accessDecisionManager; //实现权限拦截 @Autowired CustomizeFilterInvocationSecurityMetadataSource securityMetadataSource; //图片验证码过滤器 @Autowired private ValidateImageCodeFilter validateImageCodeFilter; @Autowired private CustomizeAbstractSecurityInterceptor securityInterceptor; @Bean public UserDetailsService userDetailsService() { //获取用户账号密码及权限信息 return new UserDetailsServiceImpl(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable(); //注册自定义图片验证码过滤器 http.addFilterBefore(validateImageCodeFilter, UsernamePasswordAuthenticationFilter.class); http.authorizeRequests().antMatchers("/login","/image/getImage").permitAll().anyRequest().authenticated(). // antMatchers("/login").anonymous(). // antMatchers("/**").fullyAuthenticated(). withObjectPostProcessor(new ObjectPostProcessor() { @Override public O postProcess(O o) { o.setAccessDecisionManager(accessDecisionManager);//决策管理器 o.setSecurityMetadataSource(securityMetadataSource);//安全元数据源 return o; } }). //登出 and().logout().logoutSuccessUrl("/logout") // permitAll().//允许所有用户 .logoutSuccessHandler(logoutSuccessHandler)//登出成功处理逻辑 .deleteCookies("JSESSIONID")//登出之后删除cookie //登入 .and().formLogin().loginProcessingUrl("/login") // permitAll().//允许所有用户 .successHandler(authenticationSuccessHandler)//登录成功处理逻辑 .failureHandler(authenticationFailureHandler)//登录失败处理逻辑 //异常处理(权限拒绝、登录失效等) .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)//权限拒绝处理逻辑 .authenticationEntryPoint(authenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 //会话管理 .and().sessionManagement() .maximumSessions(1)//同一账号同时登录最大用户数 .expiredSessionStrategy(sessionInformationExpiredStrategy)//会话失效(账号被挤下线)处理逻辑 ; // http.addFilterBefore(securityInterceptor, FilterSecurityInterceptor.class); } /** * 指定加密方式 */ @Bean public PasswordEncoder passwordEncoder(){ // 使用MD5加密密码 return new MD5PasswordEncoder(); } }