[英]Implement logout in Spring for Single Page Application
I'm using Java Web Token (JWT) for authentication in my web app. 我在Web应用程序中使用Java Web令牌(JWT)进行身份验证。 I want to create a
/logout
Rest endpoint that deletes the JSession cookie on the client side, invalidates the session AND does whatever else is necessary. 我想创建一个
/logout
Rest端点,该端点在客户端上删除JSession cookie,使会话无效,并执行其他必要的操作。
The front end is a SPA written in React. 前端是用React编写的SPA。
I have the following configure
method in the WebSecurityConfig
class that extends WebSecurityConfigurerAdapter
: 我在扩展
WebSecurityConfigurerAdapter
的WebSecurityConfig
类中具有以下configure
方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilterBefore(
new JWTAuthenticationFilter(userDetailsServiceBean()),
UsernamePasswordAuthenticationFilter.class);
}
I had the following code, but it returns 404 Not found
error with the path set to /login
. 我有以下代码,但其路径设置为
/login
,返回404 Not found
错误。 I want to get a HTTP response
of 200
and some cleanups instead. 我想获得
200
的HTTP response
和一些清除。 what should I do ? 我该怎么办 ?
.logout().logoutUrl("/logout").logoutSuccessHandler(logoutHandler).logoutSuccessUrl("/login").invalidateHttpSession(true)
After some research I found out that if I want to use stateless Rest API design, I shouldn't use any cookie, including JSESSIONID. 经过一番研究,我发现如果我想使用无状态Rest API设计,则不应使用任何cookie,包括JSESSIONID。
Therefore I changed my code to: 因此,我将代码更改为:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilterBefore(
new JWTAuthenticationFilter(userDetailsServiceBean()),
UsernamePasswordAuthenticationFilter.class);
}
Could you first try for login request like this. 您可以先尝试这样的登录请求吗? First add JWTLoginFilter in your WebSecurityConfig .
首先在你的WebSecurityConfig添加JWTLoginFilter。
Pasting code from my sample project: 从我的示例项目粘贴代码:
http.csrf().disable() // disable csrf for our requests.
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST,"/login").permitAll()
.anyRequest().authenticated()
.and()
// We filter the api/login requests
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in header
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class);
You wouldn't require CORSFilter if your front end and back end are on same server. 如果您的前端和后端在同一服务器上,则不需要CORSFilter。
Also find below JWTLoginFilter class 也可以在下面的JWTLoginFilter类中找到
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter
{
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(String url, AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
AccountCredentials credentials = new ObjectMapper().readValue(httpServletRequest.getInputStream(), AccountCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
String name = authentication.getName();
tokenAuthenticationService.addAuthentication(response, name);
}
}
AccountCredential class is simple POJO class containing two fields username and password, which I was using to receive the request. AccountCredential类是简单的POJO类,其中包含两个字段username和password,这是我用来接收请求的字段。
Also please note that UsernamePasswordAuthenticationFilter that we are using require two fields in login request 'username' and 'password'. 还请注意,我们使用的UsernamePasswordAuthenticationFilter在登录请求“用户名”和“密码”中需要两个字段。 Like
{"username":"user1","password":"secret1"}
像
{"username":"user1","password":"secret1"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.