Springboot中的JWT v2.4.5

Jwt in Springboot v2.4.5

我有这个 RestController:

@RestController
@Slf4j
public class AuthenticationRestController {


    @Value("${jwt.header}")
    private String tokenHeader;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserSecurityService userSecurityService;

    @Autowired
    private EmailService emailService;


    @PostMapping(path = "/api/v1/auth", consumes = "application/json", produces = "application/json")
    public ResponseEntity<JwtAuthenticationResponse>
    createAuthenticationToken(  @RequestBody JwtAuthenticationRequest authenticationRequest,
            HttpServletRequest request) throws AuthenticationException {

        LOG.info("authenticating {} " , authenticationRequest.getUsername());

        authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());

...

    /**
     * Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
     */
    private void authenticate(String username, String password) {

        Objects.requireNonNull(username);
        Objects.requireNonNull(password);


        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            e.printStackTrace();
            throw new AuthenticationException("User is disabled!", e);
        } catch (BadCredentialsException e) {
            throw new AuthenticationException("Bad credentials!", e);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

但是我在登录时出现这个错误:

org.springframework.security.authentication.DisabledException: User is disabled
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider$DefaultPreAuthenticationChecks.check(AbstractUserDetailsAuthenticationProvider.java:331)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:146)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:518)
    at com.kispackp.security.controllers.AuthenticationRestController.authenticate(AuthenticationRestController.java:138)

@Entity
@Table(name="t_user")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable, UserDetails {

    /** The Serial Version UID for Serializable classes. */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(unique = true)
    @JsonIgnore
    private String username;

    @JsonIgnore
    private String password;



    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

}

当用户未启用时会发生此错误。接口 UserDetails 有一个名为 isEnabled 的方法,在验证用户时会检查它。

AbstractUserDetailsAuthenticationProvider.java
...
if (!user.isEnabled()) {
    AbstractUserDetailsAuthenticationProvider.this.logger
            .debug("Failed to authenticate since user account is disabled");
    throw new DisabledException(AbstractUserDetailsAuthenticationProvider.this.messages
            .getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));
}
...

您应该实施它,并且 return true 在用户启用的情况下,如下所示:

public class User implements Serializable, UserDetails {

    ... your current fields and methods

    @Override
    public boolean isEnabled() {
        return true;
    }
}