我正在使用 Java Web Token(JWT)在我的网络应用中进行身份验证。我想创建一个/logout
Rest端点,删除客户端上的JSession cookie,使会话无效并执行其他必要的操作。
前端是用React编写的SPA。
我在扩展configure
的{{1}}类中使用了以下WebSecurityConfig
方法:
WebSecurityConfigurerAdapter
我有以下代码,但它返回@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);
}
错误,路径设置为404 Not found
。我希望获得/login
HTTP response
和一些清理。我该怎么办?
200
答案 0 :(得分:0)
经过一番研究后我发现如果我想使用无状态Rest API设计,我就不应该使用任何cookie,包括JSESSIONID。
因此我将代码更改为:
@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);
}
答案 1 :(得分:0)
您可以先尝试这样的登录请求吗?首先在 WebSecurityConfig 中添加 JWTLoginFilter 。
从我的示例项目中粘贴代码:
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);
如果您的前端和后端位于同一台服务器上,您将不需要CORSFilter。
另请参阅以下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类是简单的POJO类,包含两个字段用户名和密码,我用它来接收请求。
另请注意,我们使用的 UsernamePasswordAuthenticationFilter 需要登录请求中的两个字段'用户名'和密码'。与{"username":"user1","password":"secret1"}