Issue
I have this 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();
}
}
}
but I have this error when logging:
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)
and
@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;
}
}
Solution
This error happens when the user is not enabled. The interface UserDetails
has a method called isEnabled
, and it's checked when authenticating the user.
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"));
}
...
You should implement it and return true
in the case the user is enabled, like so:
public class User implements Serializable, UserDetails {
... your current fields and methods
@Override
public boolean isEnabled() {
return true;
}
}
Answered By - Marcus Hert da Coregio
Answer Checked By - Pedro (JavaFixing Volunteer)