AuthenticationManager returning Bad Credentials - spring

I have this error and I don't know what it could be. I'm following a tutorial to do the User authentication, But when I try to do the authentication it throws a "Bad credentials" but the credentials are right. I'm using MongoDB.
From the tutorial I'm following with these steps it should work (other users confirmed that they did) but the only thing I did differently from the tutorial is in the "ClientEntity" class that already existed and I just implemented what I needed.
User return:
ClientEntity(id=63166ddbe3ea6c4fffd70818, clientName=Test, clientCpf=000.000.000-00, clientEmail=teste2#example.com, clientPassword=2b598e4c0e79baf9dc9211ad303e7626, clientIsBlocked=false, clientBirthDate=1989-05-20, creditCards=[CreditCardEntity()], clientCategory=[ACAO, COMEDIA])
My request to signin, I'm logging in by email and password:
AccountCredentials: AccountCredentials(email=teste2#example.com, password=2b598e4c0e79baf9dc9211ad303e7626)
I know the problem is in that class in "authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(email, password));" but I don't know how to solve it, because the credentials are correct
My AuthService class:
#Service
public class AuthService {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private JwtTokenProvider tokenProvider;
#Autowired
private ClientRepository repository;
public ResponseEntity signin(AccountCredentials data) {
try {
var email = data.getEmail();
var password = data.getPassword();
log.info("METODO SIGNIN, AccountCredentials: " + data);
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(email, password));
log.info("FOI AUTENTICADO!");
var user = repository.findByClientEmail(email);
log.info("O valor de User é: " + user);
var tokenResponse = new Token();
if (user != null) {
tokenResponse = tokenProvider.createAccessToken(email, user.getRoles());
} else {
throw new UsernameNotFoundException("Email " + email + " not found!");
}
return ResponseEntity.ok(tokenResponse);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getCause());
System.out.println(e.getLocalizedMessage());
throw new BadCredentialsException("Invalid email/password supplied!");
}
}
public ResponseEntity refreshToken(String email, String refreshToken) {
var user = repository.findByClientEmail(email);
var tokenResponse = new Token();
if (user != null) {
tokenResponse = tokenProvider.refreshToken(refreshToken);
} else {
throw new UsernameNotFoundException("Email " + email + " not found!");
}
return ResponseEntity.ok(tokenResponse);
}
}
My ClientEntity:
#Data
#Document(collection = "Client")
public class ClientEntity implements UserDetails, Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
private String clientName;
private String clientCpf;
private String clientEmail;
private String clientPassword;
private boolean clientIsBlocked = false;
private LocalDate clientBirthDate;
private List<CreditCardEntity> creditCards;
private List<ClientCategoryEnum> clientCategory;
private List<Permission> permissions;
public List<String> getRoles() {
List<String> roles = new ArrayList<>();
for (Permission permission : permissions) {
roles.add("USER");
roles.add(permission.getDescription());
}
return roles;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.permissions;
}
#Override
public String getPassword() {
return this.clientPassword;
}
#Override
public String getUsername() {
return this.clientEmail;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
My Class Permission:
#Data
#Document(collection = "Roles")
public class Permission implements GrantedAuthority, Serializable {
private static final long serialVersionUID = 1L;
#Id
private Long id;
private String description;
#Override
public String getAuthority() {
return this.description;
}
}
My SecurityConfig:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtTokenProvider tokenProvider;
/*
#Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
*/
#Bean
public PasswordEncoder passwordEncoder() {
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
DelegatingPasswordEncoder passwordEncoder = new DelegatingPasswordEncoder("pbkdf2", encoders);
passwordEncoder.setDefaultPasswordEncoderForMatches(new Pbkdf2PasswordEncoder());
return passwordEncoder;
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(
"/auth/signin",
"/auth/refresh"
).permitAll()
.antMatchers("/api/movie_search/**").authenticated()
.and()
.cors()
.and()
.apply(new JwtConfigurer(tokenProvider));
}
}
My CLass TokenProvider:
#Service
public class JwtTokenProvider{
#Value("${security.jwt.token.secret-key:secret}")
private String secretKey = "secret";
#Value("${security.jwt.token.expire-length:3600000}")
private long validityInMilliseconds = 3600000; // 1h
#Autowired
private UserDetailsService userDetailsService;
Algorithm algorithm = null;
#PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
algorithm = Algorithm.HMAC256(secretKey.getBytes());
}
public Token createAccessToken(String email, List<String> roles) {
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
var accessToken = getAccessToken(email, roles, now, validity);
var refreshToken = getRefreshToken(email, roles, now);
return new Token(email, true, now, validity, accessToken, refreshToken);
}
public Token refreshToken(String refreshToken) {
if (refreshToken.contains("Bearer ")) refreshToken =
refreshToken.substring("Bearer ".length());
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT decodedJWT = verifier.verify(refreshToken);
String email = decodedJWT.getSubject();
List<String> roles = decodedJWT.getClaim("roles").asList(String.class);
return createAccessToken(email, roles);
}
private String getAccessToken(String email, List<String> roles, Date now, Date validity) {
String issuerUrl = ServletUriComponentsBuilder
.fromCurrentContextPath().build().toUriString();
return JWT.create()
.withClaim("roles", roles)
.withIssuedAt(now)
.withExpiresAt(validity)
.withSubject(email)
.withIssuer(issuerUrl)
.sign(algorithm)
.strip();
}
private String getRefreshToken(String email, List<String> roles, Date now) {
Date validityRefreshToken = new Date(now.getTime() + (validityInMilliseconds * 3));
return JWT.create()
.withClaim("roles", roles)
.withIssuedAt(now)
.withExpiresAt(validityRefreshToken)
.withSubject(email)
.sign(algorithm)
.strip();
}
public Authentication getAuthentication(String token) {
DecodedJWT decodedJWT = decodedToken(token);
UserDetails userDetails = this.userDetailsService
.loadUserByUsername(decodedJWT.getSubject());
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
private DecodedJWT decodedToken(String token) {
Algorithm alg = Algorithm.HMAC256(secretKey.getBytes());
JWTVerifier verifier = JWT.require(alg).build();
DecodedJWT decodedJWT = verifier.verify(token);
return decodedJWT;
}
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring("Bearer ".length());
}
return null;
}
public boolean validateToken(String token) {
DecodedJWT decodedJWT = decodedToken(token);
try {
if (decodedJWT.getExpiresAt().before(new Date())) {
return false;
}
return true;
} catch (Exception e) {
throw new InvalidJwtAuthenticationException("Expired or invalid JWT token!");
}
}
}
My ClientService:
#Service
public class ClientService implements UserDetailsService {
private final ClientRepository clientRepository;
private final ModelMapper modelMapper;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
var user = clientRepository.findByClientEmail(email);
if (user != null) {
return user;
} else {
throw new UsernameNotFoundException("Email " + email + " not found!");
}
}
}
In debug I came across this:
UsernamePasswordAuthenticationToken
Credentials=[PROTECTED], Authenticated=false, Details=null, Granted Authorities=[]]

Short answer: Passwords stored in your DB must be encrypted by PasswordEncoder.
Long answer:
You created a bean of type PasswordEncoder, so it is used by AuthenticationProvider when you call .authenticate() method of AuthenticationManager class.
As stated in java docs, DelegatingPasswordEncoder expects your passwords to be stored in DB in format like this:
{encoderId}encryptedPassword
You use pbkdf2 password encoder as a default encoder, so passwords in DB should look like this:
{pbkdf2}encryptedPassword
By the look of the returned ClientEntity, you haven't used the PasswordEncoder when you saved this entity to a DB, so the raw password is stored instead of an encrypted one.
The authentication flow should look like this:
your app registers a user, stores his password in DB in encrypted form using PasswordEncoder bean;
user passes his username (email or whatever is neccessary) and raw password to your app through login form of API endpoint;
AuthenticationProvider retrieves encrypted password from the DB and compares it with the raw password the user has provided

Related

Use of jwt for authentication and signup on springboot webflux and microservice with user in database

I am writing a microservice project with springboot that require jwt auth for spring webflux security for user in database .I have idea on how to implement jwt on basic jwt authentication on normal spring security,but it fails when applying to webflux.
The main problem is that i have no idea how to turn the entity class to "mono" class.
My tokenservice responsible for signup:
public String signup(SignupDto user){
Mono<User> saveduser=webclient.baseUrl("http://USER").build().post()
.uri("/User/adduser/")
.header(MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(
new User(
0, user.getUsername(),
passwordEncoder.encode(user.getPassword()),
user.getFullName(),
user.getEmail(),
user.getSkill_set(),user.getContact(),user.getCv(),user.getAddress_id()
,user.getAddress(),null,3
)
),User.class)
.retrieve()
.bodyToMono(User.class);
//make syn request
Mono<Authentication> authentication= reactiveAuthenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getUsername()
,user.getPassword())
);
return generateToken( authentication);
}
generate token function:
public String generateToken(Authentication authentication){
Instant now=Instant.now();
String scope=authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(" "));
String secret="AMDM:LM:LSMLdfsf";
JwtClaimsSet claims=JwtClaimsSet.builder()
.issuer("http://localhost:8080")
.issuedAt(now)
.expiresAt(now.plus(2, ChronoUnit.HOURS))
.subject(authentication.getName())
.claim("scope",scope)
.claim("secret",secret)
.build();
return this.jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
}
The webclient is calling the user at the other microservice which the api should send back the "user" class.The problem is that i cant cast the Mono class in Mono to normal authentication.
User entity:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class User {
private int id;
private String username;
private String password;
private String fullName;
private String email;
private String skill_set;
private String contact;
private String cv;
private int Address_id;
private String address;
private String role;
private double score=3.0;
The reactiveauthenticationManager bean:
#Bean
protected ReactiveAuthenticationManager reactiveAuthenticationManager() {
log.info("Received authentication request");
return authentication -> {
UserDetailsRepositoryReactiveAuthenticationManager authenticator = new UserDetailsRepositoryReactiveAuthenticationManager(securityUserService);
authenticator.setPasswordEncoder(passwordEncoder());
return authenticator.authenticate(authentication);
};
}
The SecurityUserService:
#Service
public class SecurityUserService implements ReactiveUserDetailsService {
#Autowired
private WebClient.Builder webClientBuilder;
#Override
public Mono<UserDetails> findByUsername(String username) {
return webClientBuilder.baseUrl("http://USER").build().get()
.uri(uriBuilder -> uriBuilder
.path("/User/AuthUser/{username}")
.build(username))
.retrieve()
.bodyToMono(UserAuthdto.class)
.map(
SecurityUser::new
//res->new SecurityUser(res)
)
SecurityUser:
public class SecurityUser implements UserDetails {
private final UserAuthdto user;
public SecurityUser(UserAuthdto user) {
this.user = user;
}
public int getID(){
return user.getId();
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.stream(user
.getRole()
.split(","))
.map(SimpleGrantedAuthority::new)
.toList();}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Passwword Encoder:
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
The api at the other microservice are tested and should fine.Please help to see any problem on my code.Any clue is also fine.

Error creating bean with name 'registrationListener': Unsatisfied dependency expressed through field 'service' (Showing this after building war)

These codes runs fine on my STS but not running after making jar/war.
also tried with deploying on external tomcat. what is making the differace after making the war?? i am getting lost.
This is the registration listener class
#Component
public class RegistrationListener implements ApplicationListener<OnRegistrationCompleteEvent> {
#Autowired
private IUserService service;
#Autowired
private MessageSource messages;
#Autowired
private JavaMailSender mailSender;
#Autowired
private Environment env;
// API
#Override
public void onApplicationEvent(final OnRegistrationCompleteEvent event) {
this.confirmRegistration(event);
}
private void confirmRegistration(final OnRegistrationCompleteEvent event) {
final User user = event.getUser();
final String token = UUID.randomUUID().toString();
service.createVerificationTokenForUser(user, token);
final SimpleMailMessage email = constructEmailMessage(event, user, token);
mailSender.send(email);
}
//
private SimpleMailMessage constructEmailMessage(final OnRegistrationCompleteEvent event, final User user, final String token) {
final String recipientAddress = user.getEmail();
final String subject = "Registration Confirmation";
final String confirmationUrl = event.getAppUrl() + "/registrationConfirm?token=" + token;
String message= "Your SECRET for Google Authenticator: "+user.getSecret()+"\n";
message+= messages.getMessage("message.regSuccLink", null, "You registered successfully. To confirm your registration, please click on the below link.", event.getLocale());
final SimpleMailMessage email = new SimpleMailMessage();
email.setTo(recipientAddress);
email.setSubject(subject);
email.setText(message + " \r\n" + confirmationUrl);
email.setFrom(env.getProperty("support.email"));
return email;
}
}
I have tried with #Service and without #Service tag
#Service
public interface IUserService {
User registerNewUserAccount(UserDto accountDto);
User getUser(String verificationToken);
void saveRegisteredUser(User user);
void deleteUser(User user);
void createVerificationTokenForUser(User user, String token);
VerificationToken getVerificationToken(String VerificationToken);
VerificationToken generateNewVerificationToken(String token);
void createPasswordResetTokenForUser(User user, String token);
User findUserByEmail(String email);
PasswordResetToken getPasswordResetToken(String token);
Optional<User> getUserByPasswordResetToken(String token);
Optional<User> getUserByID(long id);
void changeUserPassword(User user, String password);
boolean checkIfValidOldPassword(User user, String password);
String validateVerificationToken(String token);
String generateQRUrl(User user) throws UnsupportedEncodingException;
User updateUser2FA(boolean use2FA);
List<String> getUsersFromSessionRegistry();
NewLocationToken isNewLoginLocation(String username, String ip);
String isValidNewLocationToken(String token);
void addUserLocation(User user, String ip);
}
is this where the problem is happening?
#Service
#Transactional
public class UserService implements IUserService {
#Autowired
private UserRepository userRepository;
#Autowired
private VerificationTokenRepository tokenRepository;
#Autowired
private PasswordResetTokenRepository passwordTokenRepository;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private RoleRepository roleRepository;
#Autowired
private SessionRegistry sessionRegistry;
#Autowired
#Qualifier("GeoIPCountry")
private DatabaseReader databaseReader;
#Autowired
private UserLocationRepository userLocationRepository;
#Autowired
private NewLocationTokenRepository newLocationTokenRepository;
#Autowired
private Environment env;
public static final String TOKEN_INVALID = "invalidToken";
public static final String TOKEN_EXPIRED = "expired";
public static final String TOKEN_VALID = "valid";
public static String QR_PREFIX = "https://chart.googleapis.com/chart?chs=200x200&chld=M%%7C0&cht=qr&chl=";
public static String APP_NAME = "SpringRegistration";
// API
#Override
public User registerNewUserAccount(final UserDto accountDto) {
if (emailExists(accountDto.getEmail())) {
throw new UserAlreadyExistException("There is an account with that email address: " + accountDto.getEmail());
}
final User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
user.setEmail(accountDto.getEmail());
user.setUsing2FA(accountDto.isUsing2FA());
user.setRoles(Arrays.asList(roleRepository.findByName("ROLE_USER")));
return userRepository.save(user);
}
#Override
public User getUser(final String verificationToken) {
final VerificationToken token = tokenRepository.findByToken(verificationToken);
if (token != null) {
return token.getUser();
}
return null;
}
#Override
public VerificationToken getVerificationToken(final String VerificationToken) {
return tokenRepository.findByToken(VerificationToken);
}
#Override
public void saveRegisteredUser(final User user) {
userRepository.save(user);
}
#Override
public void deleteUser(final User user) {
final VerificationToken verificationToken = tokenRepository.findByUser(user);
if (verificationToken != null) {
tokenRepository.delete(verificationToken);
}
final PasswordResetToken passwordToken = passwordTokenRepository.findByUser(user);
if (passwordToken != null) {
passwordTokenRepository.delete(passwordToken);
}
userRepository.delete(user);
}
#Override
public void createVerificationTokenForUser(final User user, final String token) {
final VerificationToken myToken = new VerificationToken(token, user);
tokenRepository.save(myToken);
}
#Override
public VerificationToken generateNewVerificationToken(final String existingVerificationToken) {
VerificationToken vToken = tokenRepository.findByToken(existingVerificationToken);
vToken.updateToken(UUID.randomUUID()
.toString());
vToken = tokenRepository.save(vToken);
return vToken;
}
#Override
public void createPasswordResetTokenForUser(final User user, final String token) {
final PasswordResetToken myToken = new PasswordResetToken(token, user);
passwordTokenRepository.save(myToken);
}
#Override
public User findUserByEmail(final String email) {
return userRepository.findByEmail(email);
}
#Override
public PasswordResetToken getPasswordResetToken(final String token) {
return passwordTokenRepository.findByToken(token);
}
#Override
public Optional<User> getUserByPasswordResetToken(final String token) {
return Optional.ofNullable(passwordTokenRepository.findByToken(token) .getUser());
}
#Override
public Optional<User> getUserByID(final long id) {
return userRepository.findById(id);
}
#Override
public void changeUserPassword(final User user, final String password) {
user.setPassword(passwordEncoder.encode(password));
userRepository.save(user);
}
#Override
public boolean checkIfValidOldPassword(final User user, final String oldPassword) {
return passwordEncoder.matches(oldPassword, user.getPassword());
}
#Override
public String validateVerificationToken(String token) {
final VerificationToken verificationToken = tokenRepository.findByToken(token);
if (verificationToken == null) {
return TOKEN_INVALID;
}
final User user = verificationToken.getUser();
final Calendar cal = Calendar.getInstance();
if ((verificationToken.getExpiryDate()
.getTime() - cal.getTime()
.getTime()) <= 0) {
tokenRepository.delete(verificationToken);
return TOKEN_EXPIRED;
}
user.setEnabled(true);
// tokenRepository.delete(verificationToken);
userRepository.save(user);
return TOKEN_VALID;
}
#Override
public String generateQRUrl(User user) throws UnsupportedEncodingException {
return QR_PREFIX + URLEncoder.encode(String.format("otpauth://totp/%s:%s?secret=%s&issuer=%s", APP_NAME, user.getEmail(), user.getSecret(), APP_NAME), "UTF-8");
}
#Override
public User updateUser2FA(boolean use2FA) {
final Authentication curAuth = SecurityContextHolder.getContext()
.getAuthentication();
User currentUser = (User) curAuth.getPrincipal();
currentUser.setUsing2FA(use2FA);
currentUser = userRepository.save(currentUser);
final Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser.getPassword(), curAuth.getAuthorities());
SecurityContextHolder.getContext()
.setAuthentication(auth);
return currentUser;
}
private boolean emailExists(final String email) {
return userRepository.findByEmail(email) != null;
}
#Override
public List<String> getUsersFromSessionRegistry() {
return sessionRegistry.getAllPrincipals()
.stream()
.filter((u) -> !sessionRegistry.getAllSessions(u, false)
.isEmpty())
.map(o -> {
if (o instanceof User) {
return ((User) o).getEmail();
} else {
return o.toString()
;
}
}).collect(Collectors.toList());
}
#Override
public NewLocationToken isNewLoginLocation(String username, String ip) {
if(!isGeoIpLibEnabled()) {
return null;
}
try {
final InetAddress ipAddress = InetAddress.getByName(ip);
final String country = databaseReader.country(ipAddress)
.getCountry()
.getName();
System.out.println(country + "====****");
final User user = userRepository.findByEmail(username);
final UserLocation loc = userLocationRepository.findByCountryAndUser(country, user);
if ((loc == null) || !loc.isEnabled()) {
return createNewLocationToken(country, user);
}
} catch (final Exception e) {
return null;
}
return null;
}
#Override
public String isValidNewLocationToken(String token) {
final NewLocationToken locToken = newLocationTokenRepository.findByToken(token);
if (locToken == null) {
return null;
}
UserLocation userLoc = locToken.getUserLocation();
userLoc.setEnabled(true);
userLoc = userLocationRepository.save(userLoc);
newLocationTokenRepository.delete(locToken);
return userLoc.getCountry();
}
#Override
public void addUserLocation(User user, String ip) {
if(!isGeoIpLibEnabled()) {
return;
}
try {
final InetAddress ipAddress = InetAddress.getByName(ip);
final String country = databaseReader.country(ipAddress)
.getCountry()
.getName();
UserLocation loc = new UserLocation(country, user);
loc.setEnabled(true);
userLocationRepository.save(loc);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private boolean isGeoIpLibEnabled() {
return Boolean.parseBoolean(env.getProperty("geo.ip.lib.enabled"));
}
private NewLocationToken createNewLocationToken(String country, User user) {
UserLocation loc = new UserLocation(country, user);
loc = userLocationRepository.save(loc);
final NewLocationToken token = new NewLocationToken(UUID.randomUUID()
.toString(), loc);
return newLocationTokenRepository.save(token);
}
}
This is my error from jar,war,extarnal tomcat
o.s.b.f.UnsatisfiedDependencyException: Error creating bean with name 'registrationListener': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'databaseReader'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'GeoIPCountry' defined in class path resource [com/birol/spring/SecSecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.maxmind.geoip2.DatabaseReader]: Factory method 'databaseReader' threw exception; nested exception is java.io.FileNotFoundException: src\main\resources\maxmind\GeoLite2-Country.mmdb (The system cannot find the path specified)
at o.s.b.f.a.GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor$AutowiredFieldElement.resolveFieldValue(GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor.java:659)
at o.s.b.f.a.GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor$AutowiredFieldElement.inject(GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor.java:639)
at o.s.b.f.a.InjectionMetadata.inject(InjectionMetadata.java:119)
at o.s.b.f.a.GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor.postProcessProperties(GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DDor.java:399)
at o.s.b.f.s.GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DD.populateBean(GbHi8bXhDyMP2m1NDUSiYmznAJdJzX36DD.java:1431)
... 46 frames truncated

WithMockUser not working, but SecurityContext.getContext().setAuthentification does

I try to mock login with #WithMockUserbut it is not working.
#SpringBootTest
class RoleTest {
#Autowired
private UserService userService;
#Autowired
private RoleService roleService;
private User user;
#BeforeEach
void setUp() {
AuthentificationService.AuthentificationMock.loginAsAdminOnly();
user = new User("maier", "password", "Hansi", "Meier", "hanmai#maier.de", "+4953353535353", roleService.getByName(Role.ROLE_ADMIN).orElse(null));
assertNotNull(user.getRoles());
userService.save(user);
AuthentificationService.AuthentificationMock.logout();
}
#AfterEach
void tearDown() {
AuthentificationService.AuthentificationMock.loginAsAdminOnly();
userService.delete(user);
AuthentificationService.AuthentificationMock.logout();
}
#Test
#WithMockUser(Role.ADMIN)
void testRoleHierarchy() {
boolean succeeded = true;
//WHEN
try {
final Optional<User> byUsername = userService.getByUsernameResolved(user.getUsername());
} catch (Exception e) {
succeeded = false;
}
//THEN
assertTrue(succeeded, "ADMIN has no USER Privileges, check RoleHierarchy");
}
}
If I run test authentication there is an AuthenticationCredentialsNotFoundException and so test fails.
That is the Service which the access is limited:
#Service
#Slf4j
#Transactional
#NoArgsConstructor
public class UserService implements JpaServiceContract<User>, UserDetailsService {
private UserRepository userRepository;
private AuthenticationManager authenticationManager;
private PasswordEncoder passwordEncoder;
#Autowired
public UserService(PasswordEncoder passwordEncoder, AuthenticationManager authenticationManager, UserRepository userRepository) {
this.userRepository = userRepository;
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
}
#Override
public UserDetails loadUserByUsername(#NotNull String username) {
final String callerName = SharedSecrets.getJavaLangAccess().getStackTraceElement(new Throwable(), 12).getClassName();
if (!callerName.equals("app.config.security.TokenAuthenticationFilter")) {
throw new MethodAccessException();
}
SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(null, null, Collections.singletonList(new Role(Role.ADMIN))));
Optional<User> user = getByUsernameResolved(username);
SecurityContextHolder.clearContext();
final User user1 = user.orElse(null);
assert user1 != null;
return user1;
}
/**
* This Method is same as {#link #getByUsername(String)} but it resolves all Lazy loaded Properties,
* which could not be resolved outside of the current Transaction anymore
*
* #param username Of the {#link app.model.authentification.User} which should be found
* #return The {#link app.model.authentification.User} found as an {#link java.util.Optional}
*/
#RolesAllowed(value = Role.ROLE_USER)
public Optional<User> getByUsernameResolved(#NotNull String username) {
final Optional<User> userUnresolved = getByUsername(username);
userUnresolved.ifPresent(user -> Hibernate.initialize(user.getRoles()));
return userUnresolved;
}
#RolesAllowed(value = Role.ROLE_USER)
public Optional<User> getByUsername(#NotNull String username) {
if (!existsByUsername(username)) {
throw new RessourceNotFoundException("User not found");
}
return userRepository.findByUsername(username);
}
#Override
#RolesAllowed(Role.ROLE_USER)
public Optional<User> getById(#NotNull Long id) {
return userRepository.findById(id);
}
#Override
#RolesAllowed(Role.ROLE_USER)
public Optional<User> getByIdResolved(#NotNull Long id) {
final Optional<User> byId = getById(id);
if (byId.isPresent()) {
Hibernate.initialize(byId.get().getRoles());
return byId;
} else {
return Optional.empty();
}
}
#RolesAllowed(value = Role.ROLE_ADMIN)
#Override
public Set<User> getAll() {
return (Set<User>) userRepository.findAll();
}
#RolesAllowed(value = Role.ROLE_ADMIN)
#Override
public Set<User> getAllResolved() {
final Set<User> all = getAll();
Hibernate.initialize(all);
return all;
}
public User changePassword(#NotNull String oldPassword, #NotNull String newPassword) {
User user = getLoggedInUser();
user.setPassword(passwordEncoder.encode(newPassword));
return userRepository.save(user);
}
#Override
#RolesAllowed(value = Role.ROLE_USER)
public boolean existsById(#NotNull Long id) {
return userRepository.existsById(id);
}
#RolesAllowed(value = Role.ROLE_USER)
public boolean existsByUsername(#NotNull String username) {
return userRepository.existsByUsername(username);
}
#Override
#RolesAllowed(value = Role.ROLE_ADMIN)
public User save(#NotNull User user) throws RessourceAlreadyExistsException, InvalidParameterException {
if (UserValidator.isFullValid(user))
if (!userRepository.existsByUsername(user.getUsername())) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
} else {
throw new RessourceAlreadyExistsException(user.getUsername());
}
throw new InvalidParameterException(new String[]{"User"});
}
#Override
#RolesAllowed(Role.ROLE_USER)
public User update(#NotNull User user) throws InvalidParameterException {
if (UserValidator.isFullValid(user) && userRepository.existsByUsername(user.getUsername())) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
throw new InvalidParameterException(new String[]{"User"});
}
#Override
#RolesAllowed(value = Role.ROLE_ADMIN)
public void delete(#NotNull User user) throws IllegalArgumentException {
userRepository.delete(user);
}
#RolesAllowed(value = Role.ROLE_ADMIN)
public void delete(#NotNull String username) {
userRepository.deleteByUsername(username);
}
#RolesAllowed(value = Role.ROLE_USER)
private User getLoggedInUser() throws InvalidStateException {
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
String username = currentUser.getName();
final Optional<User> userValue = getByUsername(username);
if (userValue.isPresent())
return userValue.get();
throw new InvalidStateException("User " + username + " not found");
}
}
If you like to I could provide more Information of Configuration but at the Moment I don't know if this is necessary. But if you believe it is I will.

Token alway not valid

In a spring boot reactive project, with r2dbc I try to add security with jwt
#RestController
public class UserController {
private final ReactiveUserDetailsServiceImpl userService;
private final TokenProvider jwtTokenUtil;
private final JWTReactiveAuthenticationManager authenticationManager;
...
#PostMapping(value="authorize")
public Mono<JWTToken> authorize(LoginUser loginVM) {
if (loginVM ==null || loginVM.getUsername().isEmpty() || loginVM.getPassword().isEmpty()) {
return Mono.error(new RuntimeException("Bad request"));
}
Authentication authenticationToken =
new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword());
Mono<Authentication> authentication = this.authenticationManager.authenticate(authenticationToken);
authentication.doOnError(throwable -> {
throw new BadCredentialsException("Bad crendentials");
});
ReactiveSecurityContextHolder.withAuthentication(authenticationToken);
return authentication.map(auth -> {
String jwt = jwtTokenUtil.createToken(auth);
return new JWTToken(jwt);
});
}
}
#Service
public class ReactiveUserDetailsServiceImpl implements ReactiveUserDetailsService, UserService {
#Autowired
private UserRepository userRepository;
#Override
public Mono<UserDetails> findByUsername(String username) {
return userRepository.findByUsername(username)
.filter(Objects::nonNull)
.switchIfEmpty(Mono.error(new BadCredentialsException(String.format("User %s not found in database", username))))
.map(this::createSpringSecurityUser);
}
private org.springframework.security.core.userdetails.User createSpringSecurityUser(User user) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(user.getRole());
grantedAuthorities.add(grantedAuthority);
return new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(), grantedAuthorities);
}
public Flux<User> findAll(){
return userRepository.findAll();
}
}
#Component
public class TokenProvider {
private final long validityInMilliseconds = 3600000; // 1h
private static final String SALT_KEY = "123";
private String secretKey;
private final Base64.Encoder encoder = Base64.getEncoder();
private static final String AUTHORITIES_KEY = "auth";
private static final Logger logger = LogManager.getLogger(TokenProvider.class);
#PostConstruct
public void init() {
this.secretKey = encoder.encodeToString(SALT_KEY.getBytes(StandardCharsets.UTF_8));
}
public String createToken(Authentication authentication) {
String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
long now = (new Date()).getTime();
Date validity = new Date(now + this.validityInMilliseconds);
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, authorities)
.signWith(SignatureAlgorithm.HS512, secretKey)
.setExpiration(validity)
.compact();
}
public Authentication getAuthentication(String token) {
if (StringUtils.isEmpty(token) || !validateToken(token)) {
throw new BadCredentialsException("Invalid token");
}
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
Collection<? extends GrantedAuthority> authorities
= Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, token, authorities);
}
private boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.info("Invalid JWT signature.");
logger.trace("Invalid JWT signature trace: {}", e);
} catch (MalformedJwtException e) {
logger.info("Invalid JWT token.");
logger.trace("Invalid JWT token trace: {}", e);
} catch (ExpiredJwtException e) {
logger.info("Expired JWT token.");
logger.trace("Expired JWT token trace: {}", e);
} catch (UnsupportedJwtException e) {
logger.info("Unsupported JWT token.");
logger.trace("Unsupported JWT token trace: {}", e);
} catch (IllegalArgumentException e) {
logger.info("JWT token compact of handler are invalid.");
logger.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
}
public class JWTReactiveAuthenticationManager implements ReactiveAuthenticationManager {
private final ReactiveUserDetailsServiceImpl userService;
private final PasswordEncoder passwordEncoder;
private static final Logger logger = LogManager.getLogger(JWTReactiveAuthenticationManager.class);
public JWTReactiveAuthenticationManager(final PasswordEncoder passwordEncoder, final ReactiveUserDetailsServiceImpl userService) {
this.passwordEncoder = passwordEncoder;
this.userService = userService;
}
#Override
public Mono<Authentication> authenticate(Authentication authentication) {
if (authentication.isAuthenticated()) {
return Mono.just(authentication);
}
return Mono.just(authentication)
.switchIfEmpty(Mono.defer(this::raiseBadCredentials))
.cast(UsernamePasswordAuthenticationToken.class)
.flatMap(this::authenticateToken)
.publishOn(Schedulers.parallel())
.onErrorResume(e -> raiseBadCredentials())
.filter(u -> passwordEncoder.matches((String) authentication.getCredentials(), u.getPassword()))
.switchIfEmpty(Mono.defer(this::raiseBadCredentials))
.map(u -> new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), u.getAuthorities()));
}
private <T> Mono<T> raiseBadCredentials() {
return Mono.error(new BadCredentialsException("Invalid Credentials"));
}
private Mono<UserDetails> authenticateToken(final UsernamePasswordAuthenticationToken authenticationToken) {
String username = authenticationToken.getName();
logger.info("checking authentication for user " + username);
//todo change, it's not reactive
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
logger.info("authenticated user " + username + ", setting security context");
return userService.findByUsername(username);
}
return null;
}
}
#Configuration
#EnableWebFlux
#EnableWebFluxSecurity
#EnableReactiveMethodSecurity
public class SpringSecurityWebFluxConfig {
private ReactiveUserDetailsServiceImpl userService;
private TokenProvider tokenUtil;
private static final String[] AUTH_WHITELIST = {
"/resources/**",
"/webjars/**",
"/authorize/**",
"/favicon.ico",};
public SpringSecurityWebFluxConfig(TokenProvider tokenUtil, ReactiveUserDetailsServiceImpl userService) {
this.tokenUtil = tokenUtil;
this.userService = userService;
}
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, UnauthorizedAuthenticationEntryPoint entryPoint) {
http.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable();
http
.exceptionHandling()
.authenticationEntryPoint(entryPoint)
.and()
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS)
.permitAll()
.pathMatchers("/users")
.permitAll()
.and()
.addFilterAt(webFilter(), SecurityWebFiltersOrder.AUTHORIZATION)
.authorizeExchange()
.pathMatchers(AUTH_WHITELIST).permitAll()
.anyExchange().authenticated();
return http.build();
}
#Bean
public AuthenticationWebFilter webFilter() {
AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(repositoryReactiveAuthenticationManager());
authenticationWebFilter.setAuthenticationConverter(new TokenAuthenticationConverter(tokenUtil));
authenticationWebFilter.setRequiresAuthenticationMatcher(new JWTHeadersExchangeMatcher());
authenticationWebFilter.setSecurityContextRepository(new WebSessionServerSecurityContextRepository());
return authenticationWebFilter;
}
#Bean
public JWTReactiveAuthenticationManager repositoryReactiveAuthenticationManager() {
JWTReactiveAuthenticationManager repositoryReactiveAuthenticationManager = new JWTReactiveAuthenticationManager(passwordEncoder(), userService);
return repositoryReactiveAuthenticationManager;
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I try to connect with curl with this line
curl -X POST localhost:8889/authorize -u admin:123
I see in debug then validateToken receive: WRtaW46cGVybWFjb24=
Error trapped is: MalformedJwtException
Don't understand why
If i try to call directly /users (not supposed to add security) i get
curl -X GET http://localhost:8889/users
I get
Error: SEVERITY_LOCALIZED=ERROR, SEVERITY_NON_LOCALIZED=ERROR,
CODE=42601, MESSAGE=syntax error at or near ".", POSITION=12,
FILE=scan.l, LINE=1128, ROUTINE=scanner_yyerror

Spring Security and JWT in spring boot application

I am struggling a lot in understanding the concepts of spring security. I referred few examples online and tried to implement that in my project. But it is not working and I am not understanding why.
My WebConfig class is,
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
public void configureAuthentication( AuthenticationManagerBuilder authenticationManagerBuilder ) throws Exception
{
authenticationManagerBuilder.userDetailsService(this.userDetailsService);
}
#Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception
{
return new JwtAuthenticationTokenFilter();
}
#Override
protected void configure( HttpSecurity httpSecurity ) throws Exception
{
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
//.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// allow anonymous resource requests
.antMatchers(HttpMethod.GET, "/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js")
.permitAll().antMatchers("/login").permitAll().anyRequest().authenticated();
// Custom JWT based security filter
httpSecurity.addFilterBefore(authenticationTokenFilterBean(),
UsernamePasswordAuthenticationFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
}
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private JwtTokenUtil jwtTokenUtil;
#Override
protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain chain )
throws ServletException, IOException
{
final String requestHeader = "Authorization";
String username = null;
String authToken = null;
if( requestHeader != null && requestHeader.startsWith("Bearer ") )
{
authToken = requestHeader.substring(7);
try
{
username = jwtTokenUtil.getUsernameFromToken(authToken);
}
catch( IllegalArgumentException e )
{
logger.error("an error occured during getting username from token", e);
}
}
else
{
logger.warn("couldn't find bearer string, will ignore the header");
}
logger.info("checking authentication for user " + username);
if( username != null && SecurityContextHolder.getContext().getAuthentication() == null )
{
// It is not compelling necessary to load the use details from the database. You could also store the information
// in the token and read it from it. It's up to you ;)
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if( jwtTokenUtil.validateToken(authToken, userDetails) )
{
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
logger.info("authenticated user " + username + ", setting security context");
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
}
Implementation of Spring-securities UserDetailsService
#Component
public class JwtUserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserModelRepository userModelRepository;
#Override
public UserDetails loadUserByUsername( String username ) throws
UsernameNotFoundException
{
Optional<UserModel> userModelOptional =
userModelRepository.findByMobileNumberAndIsActiveTrue(username);
if( !userModelOptional.isPresent() )
{
throw new UsernameNotFoundException(String.format("No user
found with username '%s'.", username));
}
else
{
return JwtUserFactory.create(userModelOptional.get());
}
}
}
Implementation of UserDetails
public class JwtUser implements UserDetails {
private final Long id;
private final String username;
private final String firstname;
private final String lastname;
private final String password;
private final String email;
private final boolean enabled;
private final Date lastPasswordResetDate;
public JwtUser( Long id, String username, String firstname, String lastname, String email, String password,
boolean enabled, Date lastPasswordResetDate )
{
this.id = id;
this.username = username;
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
this.password = password;
this.enabled = enabled;
this.lastPasswordResetDate = lastPasswordResetDate;
}
#JsonIgnore
public Long getId()
{
return id;
}
#Override
public String getUsername()
{
return username;
}
#JsonIgnore
#Override
public boolean isAccountNonExpired()
{
return true;
}
#JsonIgnore
#Override
public boolean isAccountNonLocked()
{
return true;
}
#JsonIgnore
#Override
public boolean isCredentialsNonExpired()
{
return true;
}
public String getFirstname()
{
return firstname;
}
public String getLastname()
{
return lastname;
}
public String getEmail()
{
return email;
}
#JsonIgnore
#Override
public String getPassword()
{
return password;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities()
{
return Collections.emptyList();
}
#Override
public boolean isEnabled()
{
return enabled;
}
#JsonIgnore
public Date getLastPasswordResetDate()
{
return lastPasswordResetDate;
}
}
#Component
public class JwtTokenUtil {
static final String CLAIM_KEY_USERNAME = "sub";
static final String CLAIM_KEY_AUDIENCE = "aud";
static final String CLAIM_KEY_CREATED = "iat";
static final String AUDIENCE_UNKNOWN = "unknown";
static final String AUDIENCE_WEB = "web";
static final String AUDIENCE_MOBILE = "mobile";
static final String AUDIENCE_TABLET = "tablet";
private static final long serialVersionUID = -3301605591108950415L;
#Autowired
private TimeProvider timeProvider;
private String secret = "MySecret";
private Long expiration = 1508610600000l;
public String getUsernameFromToken( String token )
{
return getClaimFromToken(token, Claims::getSubject);
}
public Date getIssuedAtDateFromToken( String token )
{
return getClaimFromToken(token, Claims::getIssuedAt);
}
public Date getExpirationDateFromToken( String token )
{
return getClaimFromToken(token, Claims::getExpiration);
}
public String getAudienceFromToken( String token )
{
return getClaimFromToken(token, Claims::getAudience);
}
public <T> T getClaimFromToken( String token, Function<Claims, T> claimsResolver )
{
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken( String token )
{
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}
private Boolean isTokenExpired( String token )
{
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(timeProvider.now());
}
private Boolean isCreatedBeforeLastPasswordReset( Date created, Date lastPasswordReset )
{
return (lastPasswordReset != null && created.before(lastPasswordReset));
}
private String generateAudience( Device device )
{
String audience = AUDIENCE_UNKNOWN;
if( device.isNormal() )
{
audience = AUDIENCE_WEB;
}
else if( device.isTablet() )
{
audience = AUDIENCE_TABLET;
}
else if( device.isMobile() )
{
audience = AUDIENCE_MOBILE;
}
return audience;
}
private Boolean ignoreTokenExpiration( String token )
{
String audience = getAudienceFromToken(token);
return (AUDIENCE_TABLET.equals(audience) || AUDIENCE_MOBILE.equals(audience));
}
public String generateToken( UserDetails userDetails, Device device )
{
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername(), generateAudience(device));
}
private String doGenerateToken( Map<String, Object> claims, String subject, String audience )
{
final Date createdDate = timeProvider.now();
final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);
System.out.println("doGenerateToken " + createdDate);
return Jwts.builder().setClaims(claims).setSubject(subject).setAudience(audience).setIssuedAt(createdDate)
.setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact();
}
public Boolean canTokenBeRefreshed( String token, Date lastPasswordReset )
{
final Date created = getIssuedAtDateFromToken(token);
return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
&& (!isTokenExpired(token) || ignoreTokenExpiration(token));
}
public String refreshToken( String token )
{
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(timeProvider.now());
return doRefreshToken(claims);
}
public String doRefreshToken( Claims claims )
{
return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
}
public Boolean validateToken( String token, UserDetails userDetails )
{
JwtUser user = (JwtUser) userDetails;
final String username = getUsernameFromToken(token);
final Date created = getIssuedAtDateFromToken(token);
//final Date expiration = getExpirationDateFromToken(token);
return (username.equals(user.getUsername()) && !isTokenExpired(token)
&& !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()));
}
}
And the rest controller,
#RestController
public class AuthenticationRestController {
private String tokenHeader = "Authorization";
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private JwtTokenUtil jwtTokenUtil;
#Autowired
private UserDetailsService userDetailsService;
#RequestMapping( value = "login", method = RequestMethod.POST )
public ResponseEntity<?> createAuthenticationToken( #RequestBody JwtAuthenticationRequest authenticationRequest,
Device device ) throws AuthenticationException
{
// Perform the security
final Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(),
authenticationRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
// Reload password post-security so we can generate token
final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails, device);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
}
In postman I am hitting http://localhost:8080/login and I am passing username and password. In my case both username and password is the users mobile number which I stored the same as mobile number in database too. But it is showing Bad credentials. I am not understanding what is going wrong. Please help me.

Resources