Java Spring 无法正常注销

huangapple go评论105阅读模式
英文:

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:

  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:
    @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用作会话替代品的确切原因。

停止使用JWT作为会话

停止使用JWT作为会话,第2部分

JSON Web Tokens(JWT)对用户会话来说是危险的

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

Stop using JWT for sessions, part 2

JSON Web Tokens (JWT) are Dangerous for User Sessions

Why JWTs Suck as Session Tokens

huangapple
  • 本文由 发表于 2023年2月6日 06:56:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75356073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定