我正在创建一个Sping Boot 应用程序,并计划通过API请求和响应sessionId执行身份验证。
WebSecurityConfig.kt
@Configuration
@EnableWebSecurity
class WebSecurityConfig {
@Bean
fun filterChain(http: HttpSecurity, authenticationManager: AuthenticationManager): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize("/api/login", permitAll)
authorize(anyRequest, authenticated)
HttpMethod.PUT
HttpMethod.DELETE
}
csrf { disable() }
}
http.addFilter(ApiUsernamePasswordAuthenticationFilter(authenticationManager))
return http.build()
}
@Bean
fun passwordEncoder(): PasswordEncoder {
return BCryptPasswordEncoder(8)
}
@Bean
fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager {
return authenticationConfiguration.authenticationManager
}
}
字符串
UserDetailServiceImpl.kt
@Service
@Transactional
class UserDetailServiceImpl(
private val userRepository: UserRepository,
) : UserDetailsService {
override fun loadUserByUsername(username: String): UserDetails {
// Created custom UserRepository to fetch user data from database
val loginUser = userRepository.findByUsername(username)
?: throw UsernameNotFoundException("User not found")
return LoginUserDetails(loginUser)
}
}
型
ApiUsernamePasswordAuthenticationFilter.kt
data class LoginRequestParams(
val username: String,
val password: String,
)
class ApiUsernamePasswordAuthenticationFilter(authenticationManager: AuthenticationManager) :
UsernamePasswordAuthenticationFilter(authenticationManager) {
private val objectMapper = jacksonObjectMapper()
init {
setRequiresAuthenticationRequestMatcher(AntPathRequestMatcher("/api/login", "POST"))
this.setAuthenticationSuccessHandler { _, response, _ ->
response.status = HttpServletResponse.SC_OK
}
this.setAuthenticationFailureHandler { _, response, _ ->
response.status = HttpServletResponse.SC_UNAUTHORIZED
}
}
override fun attemptAuthentication(request: HttpServletRequest, response: HttpServletResponse): Authentication {
val loginRequestParams = objectMapper.readValue(request.inputStream, LoginRequestParams::class.java)
val authenticationToken =
UsernamePasswordAuthenticationToken(loginRequestParams.username, loginRequestParams.password)
return authenticationManager.authenticate(authenticationToken)
}
}
型
现在登录请求正确地得到200,但是没有返回set-cookie
头,所以我不能保持登录状态。
curl -X POST -H "Content-Type: application/json" -d '{"username": "lipsum", "password": "example"}' http://localhost:8080/api/login -i -c cookie.txt
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Thu, 23 Nov 2023 09:29:51 GMT
型
我认为Spring Security会自动生成jsessionid
,我想使用它,但是需要更多的设置吗?
1条答案
按热度按时间piah890a1#
我的例子是通过REST API执行身份验证,在这种情况下,我需要使用
SecurityContextRepository
显式地保存用户信息。https://spring.pleiades.io/spring-security/reference/servlet/authentication/passwords/#publish-authentication-manager-bean
而且正如Toerktumbery所说,我退出了自定义过滤器,而是通过向配置中添加
AuthenticationManager
bean来使用另一个控制器。WebSecurityConfig.kt
字符串
LoginController.kt
型
UserDetailServiceImpl.kt
相同,ApiUsernamePasswordAuthenticationFilter.kt
被移除。现在服务器响应
Set-Cookie
头。型