【问题标题】:Why Spring filter is always invoked?为什么总是调用 Spring 过滤器?
【发布时间】:2020-04-07 19:31:32
【问题描述】:

我正在使用 Spring Boot 框架 实现 REST API。我有一个公共服务/auth/login

@PostMapping("/auth/login")
fun login(@RequestBody loginRequest: LoginRequest): String {
    val token = tokenProvider.generateToken(loginRequest.username, loginRequest.password)
    if (token === null) {
        throw NotLoggedInError()
    }   
    return token
} 

它可用于检索安全区域/api/schemas的令牌:

@GetMapping
fun getSchemas() : ArrayList<Schema> = _schemas

我已经在自定义 WebSecurityConfigurerAdapter 对象的 configure(http: HttpSecurity?) 方法中配置了我的安全策略:

override fun configure(http: HttpSecurity?) {
    http!!
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .exceptionHandling()
                .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
                .and()
            .authenticationProvider(tokenAuth)
                .addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter::class.java)
                .authorizeRequests()
                .requestMatchers(PROTECTED_URLS).authenticated()
                .and()
            .csrf().disable()
            .formLogin().disable()
            .httpBasic().disable()
            .logout().disable()
} 

似乎总是调用过滤器的attemptAuthentication方法,即使是在公共区域访问的情况下。

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
class TokenAuthenticationFilter(requiresAuth: RequestMatcher) : AbstractAuthenticationProcessingFilter(requiresAuth) {

    @Autowired
    lateinit var tokenAuthenticationProvider: TokenAuthenticationProvider

    private val BEARER = "Bearer"

    override fun attemptAuthentication(request: HttpServletRequest?, response: HttpServletResponse?): Authentication {
        val param: String? = request!!.getHeader("Authorization")
        val token = removeStart(param!!, BEARER).trim()
        val user = tokenAuthenticationProvider.getUserFromToken(token)
        val auth = UsernamePasswordAuthenticationToken(user!!.username, user.password)
        return authenticationManager.authenticate(auth)
    }

    override fun successfulAuthentication(request: HttpServletRequest?, response: HttpServletResponse?, chain: FilterChain?, authResult: Authentication?) {
        super.successfulAuthentication(request, response, chain, authResult)
        chain!!.doFilter(request, response)
    }

    override fun unsuccessfulAuthentication(request: HttpServletRequest?, response: HttpServletResponse?, failed: AuthenticationException?) {
        throw NotLoggedInError()
    }
}

有什么想法吗?提前感谢您的帮助。

问候。

【问题讨论】:

    标签: java spring spring-boot kotlin


    【解决方案1】:

    从技术上讲,Spring Security总是对用户进行身份验证。在不需要身份验证的情况下(例如公共端点),用户仍然匿名身份进行身份验证。

    在您的WebSecurityConfigurerAdapter#configure(HttpSecurity) 中,您明确地将restAuthenticationFilter() 之前 AnonymousAuthenticationFilter::class.java。这意味着 Spring Security 将用户身份验证为匿名用户,它首先需要调用您的过滤器,然后才能调用 AnonymousAuthenticationFilter

    【讨论】:

    • 我不确定。我已经更改了过滤器中的顺序,将对 addFilterBefore 的调用替换为 addFilterAfter,但它仍然不起作用。
    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2011-12-17
    • 2021-05-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多