如何在 Filter 中调用服务层
问题产生的背景
集成spring-secrity时,需求是希望在jwt Filter中调用UserService以及自定义的UserDetailService,当通过注解**@Resource**注入,报方法为 null
问题产生原因
web应用启动的顺序是:listener->filter->servlet
|
拦截器加载的时间点在 springcontext 之前,所以在拦截器中注入自然为 null
解决方法
ServletContext context = request.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); UserService userService = ctx.getBean(UserService.class); MyUserDetailServiceImpl myUserDetailService = ctx.getBean(MyUserDetailServiceImpl.class);
|
spring-security 5.7.1 新版本配置
版本迭代导致部分类被移除
在Spring Security的5.7.x版本下,WebSecurityConfigurerAdapter类已经被废弃,后续版本将被移除,所以更新POM后WebSecurityConfigurerAdapter有弃用告警(已被标记@Deprecated),但依旧可以使用。
|
升级前
类似代码
SecurityConfig
类继承WebSecurityConfigurerAdapter
- 需要重写
Adapter
中的三个方法进行配置
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http ... .antMatcher("/**") .authorizeRequests(authorize -> authorize .anyRequest().authenticated() ); } }
|
升级后
- 通过
@Bean
方式注入
- 不再继承
WebSecurityConfigurerAdapter
,只需直接声明配置类,再配置一个生成SecurityFilterChainBean
的方法,把原来的HttpSecurity
配置移动到该方法中
- 自定义的方法同样通过
@Bean
注入
类似代码
@Configuration public class SecurityConfig {
@Bean SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity. ... .formLogin() .usernameParameter("userAccount") .passwordParameter("userPassword") ... .addFilter(new JwtAuthenticationFilter(authenticationManager)); return httpSecurity.build(); }
}
@Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); }
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); }
|
spring-security 前端适配自带的 login 方法
spring-security
默认有一个登录方法,前端需要适配一下, 我前端登录页已经开发完成,所以修改的security
配置,将默认的username
和password
自定义和前端一样,默认请求的 url 为/login
- 前端的请求方式需要改变,由原先的
json
改成form
提交
import qs from 'qs' ....//s export function loginRequest(loginParam: IAccount) { return hyRequest.post({ url: '/api/login', data: qs.stringify(loginParam), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
|
httpSecurity. ... .formLogin() .usernameParameter("userAccount") .passwordParameter("userPassword")
|