问题描述
在我的 Spring Boot 应用程序中,我想添加注销链接.
In my spring boot app I want to add link to logout.
在模板welcome.html:
In template welcome.html:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title th:text="${appName}">Template title</title>
<body>
<h1>Welcome to <span th:text="${appName}">Our App</span></h1>
<h2>Dictionaries:</h2>
<p><a href="/categories">Categories</a></p>
<p><a href="/users">Users</a></p>
<p><a href="/logout">Logout</a></p>
</body>
</html>
在我的SecurityConfiguration
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.web.DefaultRedirectStrategy;
import ru.otus.software_architect.eshop.handler.CustomLogoutSuccessHandler;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource; // get by Spring
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// Here, you are making the public directory on the classpath root available without authentication (e..g. for css files)
.antMatchers("/public/**", "/registration.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.successHandler((request, response, authentication) -> new DefaultRedirectStrategy().sendRedirect(request, response, "/welcome"))
.failureUrl("/login-error.html")
.permitAll()
.and()
.logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.permitAll();
}
// login by user from db
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.usersByUsernameQuery("SELECT username, password, active FROM usr WHERE username=?")
.authoritiesByUsernameQuery("SELECT u.username, ur.role FROM usr u INNER JOIN user_roles ur ON u.id = ur.user_id WHERE u.username=?");
}
我的处理程序:
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
private static Logger logger = LogManager.getLogger(CustomLogoutSuccessHandler.class);
@Override
public void onLogoutSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
logger.info("onLogoutSuccess:");
// some custom logic here
response.sendRedirect(request.getContextPath() + "/login.html");
}
}
正如你所看到的,它只是转发到登录页面.
as you can see it just forward to login page.
但是当我在注销链接上单击welcome.html 时,方法onLogoutSuccess
不会被调用并且我得到错误页面:
But when I click on welcome.html on logout link the method onLogoutSuccess
is not call and I get error page:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Jan 26 18:21:53 EET 2020
There was an unexpected error (type=Not Found, status=404).
No message available
推荐答案
Logout</a>
会将您重定向到 "/logout"
执行 GET
请求.
除非您在 "/logout"
处呈现页面,否则您将收到 404.
<a href="/logout">Logout</a>
will redirect you to "/logout"
performing a GET
request.
Unless you have a page rendered at "/logout"
, you will receive a 404.
默认情况下,登出仅在向 "/logout"
发出 POST
请求时触发.
By default logout is only triggered with a POST
request to "/logout"
.
由于您使用的是 Thymeleaf,因此您可以改用类似这样的方法来注销.
Since you are using Thymeleaf, you could instead use something like this for logging out.
<form action="#" th:action="@{/logout}" method="post">
<input type="submit" value="Logout" />
</form>
这篇关于无法通过自定义注销处理程序注销的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!