首页 > 解决方案 > 403 Forbidden on using JWT Authorization in springboot

问题描述

我试图在springboot中实现基本的身份验证和授权。但是当我向端点发送获取请求时出现 403 Forbidden 错误。我已经在 Authorization 标头中添加了 JWT 令牌。我正在尝试向“/user”发送获取请求。 在此处输入图像描述

这是我写的代码

用户控制器

@RequestMapping(value = "/user")
@RestController
public class UserController {

@Autowired
UserService userService;

@PostMapping
public UserDetailsResponseModel createUser(@RequestBody UserDetailsRequestModel userRequestObject)
{
    UserDetailsResponseModel userResponse = new UserDetailsResponseModel();
    UserDTO userDto = new UserDTO();
    BeanUtils.copyProperties(userRequestObject,userDto);
    UserDTO createdUser = userService.createUser(userDto);
    BeanUtils.copyProperties(createdUser,userResponse);
    return userResponse;
}

@GetMapping
public String getUser()
{
    return "Get user was called";
}
}

网络安全类

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private final UserService userService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;

public WebSecurity(UserService userService,BCryptPasswordEncoder bCryptPasswordEncoder)
{
    this.userService = userService;
    this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}

protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilter(new AuthenticationFilter(authenticationManager()))
            .addFilter(new AuthorizationFilter(authenticationManager()));
}

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
}
}

授权过滤器

public class AuthorizationFilter extends BasicAuthenticationFilter {
public AuthorizationFilter(AuthenticationManager authenticationManager)
{
    super(authenticationManager);
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

    String header = request.getHeader(SecurityConstants.HEADER_STRING);

    if(header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX));
    {
        chain.doFilter(request,response);
    }

    UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    chain.doFilter(request,response);
}

private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
    String token = request.getHeader(SecurityConstants.HEADER_STRING);

    token = token.replace(SecurityConstants.TOKEN_PREFIX,"");

    String user = Jwts.parser()
                .setSigningKey(SecurityConstants.TOKEN_SECRET)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();


    if(user != null){
        return new UsernamePasswordAuthenticationToken(user,null,new ArrayList<>());
    }

    return null;
}
}

身份验证过滤器

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;

public  AuthenticationFilter(AuthenticationManager authenticationManager)
{
    this.authenticationManager = authenticationManager;
}


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

    try {
        UserLoginRequestModel creds = new ObjectMapper().readValue(request.getInputStream(),UserLoginRequestModel.class);

        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        creds.getEmail(),
                        creds.getPassword(),
                        new ArrayList<>()
                )
        );
    }
    catch (IOException ex){
        throw new RuntimeException(ex);
    }

}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {

    String userName = ((User) authResult.getPrincipal()).getUsername();

    String token = Jwts.builder()
                    .setSubject(userName)
                    .setExpiration(new Date(System.currentTimeMillis()+SecurityConstants.EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512,SecurityConstants.TOKEN_SECRET)
                    .compact();
    UserService userService = (UserService) SpringApplicationContext.getBean("userServiceImplementation");
    UserDTO userDTO = userService.getUser(userName);
    response.addHeader(SecurityConstants.HEADER_STRING,SecurityConstants.TOKEN_PREFIX+token);
    response.addHeader("UserID",userDTO.getUserId());
}
}

标签: spring-bootjwt

解决方案


推荐阅读