Spring Security Filter 测试,身份验证在 POSTMAN 中不起作用

Posted

技术标签:

【中文标题】Spring Security Filter 测试,身份验证在 POSTMAN 中不起作用【英文标题】:Spring Security Filter test, authentification not working in POSTMAN 【发布时间】:2020-06-06 06:22:20 【问题描述】:

我正在尝试检查尝试身份验证是否正常工作,但在邮递员中但我得到 401 未经授权。

我的安全配置:

 @Override
protected void configure(HttpSecurity http) throws Exception 
    http.csrf().disable();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    //http.formLogin();
    http.authorizeRequests().antMatchers("/login","/login/**","/register/**").permitAll();
    http.authorizeRequests().antMatchers(HttpMethod.POST,"/tasks/**").hasAuthority("ADMIN");
    http.authorizeRequests().anyRequest().authenticated();
    http.addFilter(new JWTAuthenticationFilter(authenticationManager()));
    http.addFilterBefore(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);



我的尝试验证:

@Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException 

        AppUser appUser = null;
        try 

            appUser = new ObjectMapper().readValue(request.getInputStream(), AppUser.class);
         catch (Exception e) 
            throw new RuntimeException(e);
        
        System.out.println("****************************");
        System.out.println(appUser.getUsername());
        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(appUser.getUsername(), appUser.getPassword()));
    

我的邮递员测试:

我的 JWTAuthenticationFilter:

package security;

import java.io.IOException;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.example.springJWT.entities.AppUser;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;



public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter


    private AuthenticationManager authenticationManager;    


    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) 
        super();
        //      super.setFilterProcessesUrl("/login");

        this.authenticationManager = authenticationManager;
    

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException 

        AppUser appUser = null;
        try 

            appUser = new ObjectMapper().readValue(request.getInputStream(), AppUser.class);
         catch (Exception e) 
            throw new RuntimeException(e);
        
        System.out.println("****************************");
        System.out.println(appUser.getUsername());
        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(appUser.getUsername(), appUser.getPassword()));
    

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
            Authentication authResult) throws IOException, ServletException 
        User springUser=(User) authResult.getPrincipal();
        String jwt=Jwts.builder()
                .setSubject(springUser.getUsername())
                .setExpiration(new Date(System.currentTimeMillis()+SecurityConstants.EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SecurityConstants.SECRET)
                .claim("roles", springUser.getAuthorities())
                .compact();
        response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX+jwt);
        super.successfulAuthentication(request, response, chain, authResult);
    

【问题讨论】:

以用户名和密码作为标题中的键和值发布 我试过了,还是一样的错误 你尝试调试了吗? 【参考方案1】:

attemptAuthentication 方法中的 JWTAuthenticationFilter 类中,您正在向身份验证管理器提供 UsernamePasswordAuthenticationToken

它有一个 String 实例作为主体,并且在 successfulAuthentication 方法中,您尝试将其强制转换为用户

User springUser=(User) authResult.getPrincipal();

如果我尝试会出错,但这取决于您实际使用的 AuthenticationProvider

【讨论】:

您可以在属性中添加 logging.level.org.springframework.security= debug 并在使用 postman 调用 login 时添加日志输出吗? 谢谢,但是问题出在包本身,spring看不到,我只是把它从security改成了com.example.springJWT.security,不知道怎么没意识到早点..

以上是关于Spring Security Filter 测试,身份验证在 POSTMAN 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security(09)——Filter

spring-security-01

Spring实战----源码解析Spring Security4.1.3中的过滤器Filter配置

Spring-Security 自定义Filter完成验证码校验

关于Spring Security的笔记

Spring Security 梳理 - DelegatingFilterProxy