英文:
Java Spring cannot logout properly
问题
I understand your request. Here's the translation of the code you provided, excluding the code itself:
I understand this question has been asked before, but none of what worked for the others worked for me. That said, here it is:
After setting up `.logout()` and its relevant associate methods, I still cannot make my Spring server logout properly. To be precise, this is the sequence I'm following:
1. `POST` login, get token
2. Use token for other HTTP requests, such as a standard `GET` for DB data
3. Logout using the vanilla logout URL
4. Try to do step 2 again, to see if logout was successful.
At 4, for a reason that is unknown to me, I'm still able to `GET` the data, which is wrong.
Some of the things I've tried are:
- `.clearAuthentication(true).invalidateHttpSession(true)`
- Setting up the following bean on my `SecurityConfig`:
None of it worked. Below are my security configurations. Any clues and help is much appreciated, and I thank you in advance.
SecurityConfig.java
If you have any further code or text that you'd like to be translated, please provide it, and I'll be happy to assist you.
英文:
I understand this question has been asked before, but none of what worked for the others worked for me. That said, here it is:
After setting up .logout()
and its relevant associate methods, I still cannot make my Spring server logout properly. To be precise, this is the sequence I'm following:
POST
login, get token- Use token for other HTTP requests, such as a standard
GET
for DB data - Logout using the vanilla logout URL
- Try to do step 2 again, to see if logout was successful.
At 4, for a reason that is unknown to me, I'm still able toGET
the data, which is wrong.
Some of the things I've tried are:
.clearAuthentication(true).invalidateHttpSession(true)
- Setting up the following bean on my
SecurityConfig
:
@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}
None of it worked. Below are my security configurations. Any clues and help is much appreciated, and I thank you in advance.
SecurityConfig.java
@Configuration
public class SecurityConfig {
@Autowired
private AuthenticationManager authenticationManager;
private final AuthSuccessHandler authSuccessHandler;
private final JwtUserDetailsService jwtUserDetailsService;
private final String secret;
SecurityConfig(AuthSuccessHandler authSuccessHandler, JwtUserDetailsService jwtUserDetailsService, @Value("${jwt.secret}") String secret) {
this.authSuccessHandler = authSuccessHandler;
this.jwtUserDetailsService = jwtUserDetailsService;
this.secret = secret;
}
@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeHttpRequests((auth) -> {
try {
auth
.requestMatchers("/user").hasRole("USER")
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("**/encoding-results/**", "**/encoding-results").hasAnyRole("ADMIN")
.requestMatchers("**/video/**").hasAnyRole("ADMIN")
.requestMatchers("**/codec/**").hasAnyRole("ADMIN")
.requestMatchers("**/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(authenticationFilter())
.addFilter(new JwtAuthorizationFilter(authenticationManager, jwtUserDetailsService, secret))
.logout(logout -> logout
.clearAuthentication(true)
.logoutUrl("/logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID"))
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public JsonObjectAuthenticationFilter authenticationFilter() throws Exception {
JsonObjectAuthenticationFilter filter = new JsonObjectAuthenticationFilter();
filter.setAuthenticationSuccessHandler(authSuccessHandler);
filter.setAuthenticationManager(authenticationManager);
return filter;
}
}
答案1
得分: 2
你无法注销JWT,只要设置了验证时间,JWT就有效。
OWASP已经对这个问题进行了描述用户无内置令牌吊销。
你编写了一个自定义的登录程序,用于颁发令牌。服务器不知道发放了多少令牌,以及哪些令牌已登录或未登录。
因此,除非在服务器端保留已发放令牌的某种状态,例如将令牌存储在数据库中,并在某人注销时使其无效,否则无法注销用户。
当然,删除sessionid cookie不会产生任何效果,因为你没有使用会话cookie。
这正是为什么不应该将JWT用作会话替代品的确切原因。
JSON Web Tokens(JWT)对用户会话来说是危险的
英文:
You cant logout a JWT, a JWT is valid as long as you have set the validation time to be.
OWASP has written about this problem No Built-In Token Revocation by the User
You have written a custom login that issues tokens. The server has no idea how many tokens that have been issued and which tokens that are logged in or not.
So no you can't logout the user, unless you keep some form of state of the issued tokens on the server side, as in storing the tokens in a database and invalidating them when someone does a logout.
And ofc deleting the sessionid cookie wont do anything since you are not using session cookies.
This is the exact reason why you shouldn't be using JWTs as session replacements.
Stop using JWT for sessions, part 2
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论