如何成功退出

Posted

技术标签:

【中文标题】如何成功退出【英文标题】:How to log out sucessfully 【发布时间】:2019-05-19 01:51:10 【问题描述】:

我的登录页面是http://localhost:8080/nradmin/welcome 我的主页(成功登录后)是http://localhost:8080/nradmin/home

我想退出,不再能够访问任何其他页面,例如主页,而只能访问欢迎(登录)页面。如果我在注销后在浏览器上输入http://localhost:8080/nradmin/home,我将继续访问主页而无需登录。

我已经实现了从抽象类 WebSecurityConfigurerAdapter 覆盖的以下方法:

@Override
protected void configure(HttpSecurity http) throws Exception        http
     .authorizeRequests()
        .antMatchers("/welcome").permitAll()
        .antMatchers("/home", "/account/**", "/price/**").hasRole("ADMIN")
        .antMatchers("/home", "/account/**", "/price/**").access("hasRole('ROLE_ADMIN')")
        .anyRequest()
        .authenticated()
        .and()
     .formLogin()
        .loginPage("/welcome")  
        .defaultSuccessUrl("/home")
        .and()
     .logout()
        .invalidateHttpSession(true)      
        .clearAuthentication(true)
        .logoutSuccessUrl("/welcome")    
        .logoutUrl("/welcome")          
        .deleteCookies()
        .permitAll()
        .and()
     .exceptionHandling()
        .accessDeniedPage("/welcome")           
        .and()
     .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);



@Override   
protected void configure(final AuthenticationManagerBuilder auth) throws Exception         
auth.inMemoryAuthentication()           .withUser("username").password(passwordEncoder().encode("12345")).roles(LoginDataConstants.ROLE_ADMIN)
    
@Bean
public PasswordEncoder passwordEncoder() 
    return new BCryptPasswordEncoder();

有人知道怎么做吗?

【问题讨论】:

【参考方案1】:

我猜这可能是由于方法logoutUrllogoutSuccessUrl 中的url 相同。

我建议您将logoutUrl 更改为其他路径,例如只是/logout,然后尝试执行注销访问该网址。它应该完成注销任务并重定向到logoutSuccessUrl,即/welcome

【讨论】:

我已经改变了你所说的方法配置,并创建了一个文件 logout.html。但它仍然无法正常工作。【参考方案2】:

添加CSRF

来自 spring 文档的参考。

将使用 URL 执行注销 / 使用任何 HTTP 方法请求注销

@Override protected void configure(HttpSecurity http) throws Exception  
http.
logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")); 
   

您还可以使用相同的方法here 参考有关堆栈溢出的一个很好的示例

当我遇到这个问题时,我使用了这条线

.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");

在哪里

.logoutSuccessUrl("/login") 是用户将被重定向到的页面。

你可以把你的代码重构成这样的

@Override
protected void configure(HttpSecurity http) throws Exception        http
     .authorizeRequests()
        .antMatchers("/welcome").permitAll()
        .antMatchers("/home", "/account/**", "/price/**").hasRole("ADMIN")
        .antMatchers("/home", "/account/**", "/price/**").access("hasRole('ROLE_ADMIN')")
        .anyRequest()
        .authenticated()
        .and()
     .formLogin()
        .loginPage("/welcome")  
        .defaultSuccessUrl("/home")
        .and()
     .logout()
     .and() // This section is re-factored.
        .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/welcome").deleteCookies("JSESSIONID") //Or try .logoutSuccessUrl("/nradmin/welcome") 
        .invalidateHttpSession(true)
        .permitAll()
        .and()
     .exceptionHandling()
        .accessDeniedPage("/welcome")           
        .and()
     .sessionManagement()
        .sessio hinCreationPolicy(SessionCreationPolicy.IF_REQUIRED);

更新:这是修改后的版本。除了这部分之外,这基本上是我在项目中使用的:

.and()
.exceptionHandling()
.accessDeniedPage("/welcome")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);

所以,我相信它应该有效;否则,我相信它可能是位于您项目中其他地方的设置问题/配置。请尝试以下示例。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
        .authorizeRequests()
        .antMatchers("/nradmin/welcome", "/home", "/account/**", "/price/**").hasRole("ADMIN")
        .anyRequest().permitAll()
        .and()
        .formLogin()
        .loginPage("/nradmin/welcome")
        .permitAll()
        .and()
        .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/nradmin/welcome").deleteCookies("JSESSIONID") 
        .invalidateHttpSession(true)
        .permitAll()
        .and()
        .exceptionHandling()
        .accessDeniedPage("/nradmin/welcome")
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
    

【讨论】:

@Jacqueline Cavalcanti - 你试过我的例子吗?它应该可以工作。 我将上面的示例编辑为 .logoutSuccessUrl("/welcome") 而不是 .logoutSuccessUrl("/login")。请重试。 当您注销时,重定向 url 应该类似于 localhost:8080/logout。然后你应该看到你的“/welcome”页面。现在,这不起作用,您可以尝试按照原始帖子中的说明将 .logoutSuccessUrl("/welcome") 更改为 .logoutSuccessUrl("/nradmin/welcome ")。 问题不在于我无法注销并进入欢迎页面。在按注销后,更改为欢迎页面有效。但是,如果我在浏览器 url 上键入 link,即使在注销后我仍然可以访问主页。 我明白了。问?是否需要这个 ".antMatchers("/home", "/account/**", "/price/**").access("hasRole('ROLE_ADMIN')")" 如果不需要你可以评论吗出去。这是我能看到的最后一件事;否则,如果使用我上面的示例不起作用,则可能是您设置中的其他内容。

以上是关于如何成功退出的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flutter 成功登录和退出 Firebase?

如何运行失败后不退出的命令,直到成功?

当成功有时会导致退出代码为 1 时,如何可靠地确定 pg_restore 是不是成功?

使gdb在成功终止时自动退出?

在 Node.js 中如何停止脚本执行,成功向控制台写入错误消息,然后退出脚本?

合并工具应如何指示合并成功?