Implementing Token and Role Base Authentication Using Spring Boot + JWT+ mongoDB - java

Can any one suggest me another solution or how i can fixed this issue please.and thank's by advance
cotroller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.JwtRequest;
import com.example.demo.entity.JwtResponse;
import com.example.demo.service.JwtService;
#RestController
#CrossOrigin
public class JwtController {
#Autowired
private JwtService jwtService;
#PostMapping({"/authenticate"})
public JwtResponse createJwtToken(#RequestBody JwtRequest jwtRequest) throws Exception {
return jwtService.createJwtToken(jwtRequest);
}
}
service
package com.example.demo.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.example.demo.dao.UserDao;
import com.example.demo.Util.JwtUtil;
import com.example.demo.entity.User;
import com.example.demo.entity.JwtResponse;
import com.example.demo.entity.JwtRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.HashSet;
import java.util.Set;
#Service
public class JwtService implements UserDetailsService {
#Autowired
private JwtUtil jwtUtil;
#Autowired
private UserDao userDao;
#Autowired
private AuthenticationManager authenticationManager;
public JwtResponse createJwtToken(JwtRequest jwtRequest) throws Exception {
String userName = jwtRequest.getName();
String userPassword = jwtRequest.getUser_code();
authenticate(userName, userPassword);
UserDetails userDetails = loadUserByUsername(userName);
String newGeneratedToken = jwtUtil.generateToken(userDetails);
User user = userDao.findById(userName).get();
return new JwtResponse(user, newGeneratedToken);
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findById(username).get();
if (user != null) {
return new org.springframework.security.core.userdetails.User(
user.getName(),
user.getUser_code(),
getAuthority(user)
);
} else {
throw new UsernameNotFoundException("User not found with username: " + username);
}
}
private Set getAuthority(User user) {
Set<SimpleGrantedAuthority> authorities = new HashSet<>();
user.getRoles().forEach(role -> {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
});
return authorities;
}
private void authenticate(String userName, String userPassword) throws Exception {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName, userPassword));
} catch (DisabledException e) {
throw new Exception("USER_DISABLED");
} catch (BadCredentialsException e) {
throw new Exception("INVALID_CREDENTIALS");
}
}
}
WebSecurityConfiguration
package configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Autowired
private UserDetailsService jwtService;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors();
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate", "/registerNewUser").permitAll()
.antMatchers(HttpHeaders.ALLOW).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(jwtService).passwordEncoder(passwordEncoder());
}
}
error
Description:
Field authenticationManager in com.example.demo.service.JwtService required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.security.authentication.AuthenticationManager' in your configuration.

i too had a same problem i fixed by
declaring name of the bean
#Bean(name= BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

Related

Parameter 0 of constructor in AuthService required a bean of type 'springframework.security.crypto.password.PasswordEncoder' that could not be found

Below you will find the 2 classes that I think you guys need. If any more info is required please let me know.
AuthService
package com.r.reservationproject.services;
import com.r.reservationproject.dto.AuthenticationResponse;
import com.r.reservationproject.dto.RegisterRequest;
import com.r.reservationproject.domain.NotificationEmail;
import com.r.reservationproject.domain.User;
import com.r.reservationproject.domain.VerificationToken;
import com.r.reservationproject.dto.LoginRequest;
import com.r.reservationproject.exceptions.SpringReservationAccountException;
import com.r.reservationproject.repositories.UserRepo;
import com.r.reservationproject.repositories.VerificationTokenRepo;
import com.r.reservationproject.security.JwtProvider;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotBlank;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
#Service
#AllArgsConstructor
#Transactional
// Contains logic to create username password authentication token and use authenticationManager to perform login
public class AuthService {
private final PasswordEncoder passwordEncoder;
private final UserRepo userRepo;
private final VerificationTokenRepo verificationTokenRepo;
private final MailService mailService;
private final AuthenticationManager authenticationManager;
private final JwtProvider jwtProvider;
public void signup(RegisterRequest registerRequest) {
User user = new User();
user.setUsername(registerRequest.getUsername());
user.setEmail(registerRequest.getEmail());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
user.setCreated(Instant.now());
user.setEnabled(false);
userRepo.save(user);
String token = generateVerificationToken(user);
mailService.sendMail(new NotificationEmail("Activeren account applicatie", user.getEmail(),
"Bedankt voor het gebruiken van onze applicatie, om uw account te activeren vragen wij u om volgende link te klikken :" +
"http://localhost:8080/api/auth/accountVerification/" + token));
}
private String generateVerificationToken(User user) {
String token = UUID.randomUUID().toString();
VerificationToken verificationToken = new VerificationToken();
verificationToken.setToken(token);
verificationToken.setUser(user);
verificationTokenRepo.save(verificationToken);
return token;
}
public void verifyAccount(String token) {
Optional<VerificationToken> verificationToken = verificationTokenRepo.findByToken(token);
verificationToken.orElseThrow(() -> new SpringReservationAccountException("Token is niet geldig"));
fetchUserAndEnable(verificationToken.get());
}
public void fetchUserAndEnable(VerificationToken verificationToken) {
#NotBlank(message = "Username is required") String username = verificationToken.getUser().getUsername();
User user = userRepo.findByUsername(username).orElseThrow(() -> new SpringReservationAccountException("Gebruiker onbekend"));
user.setEnabled(true);
userRepo.save(user);
}
public AuthenticationResponse login(LoginRequest loginRequest) {
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authenticate);
String token = jwtProvider.generateToken(authenticate);
// to send this token we use a dto (authenticationresponse)
return new AuthenticationResponse(token, loginRequest.getUsername());
}
}
SecurityConfig
package com.r.reservationproject.config;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#EnableWebSecurity
#AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
#Bean(BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
}
#Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
}
Full error:
APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in com.r.reservationproject.services.AuthService required a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' in your configuration.
I don't get the error since I already defined the Bean in the SecurityConfig
I appreciate your help a lot!
Try adding #Configuration annotation in your SecurityConfig class

Can't require authentication for a specific endpoint using Spring Security

I want to require authentication for my endpoints that start with "/chat/..." (on GET requisitions). I have done some basic configuration but it doesn't seem to be working. Even after authenticating a user and using its generated JWT Token, Postman still returns code 403 (Forbidden) for me. What could I be doing wrong?
My SecurityConfig class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private Environment env;
#Autowired
private JWTUtil jwtUtil;
private static final String[] PUBLIC_MATCHERS_GET = {
"/usuarios/**",
};
private static final String[] PUBLIC_MATCHERS = {
"/login/**"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests()
.antMatchers(HttpMethod.GET, PUBLIC_MATCHERS_GET).permitAll()
.antMatchers(PUBLIC_MATCHERS).permitAll()
.antMatchers(HttpMethod.GET, "/chat/**").authenticated()
.anyRequest().authenticated();
http.addFilter(new JWTAuthenticationFilter(authenticationManager(), jwtUtil));
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
My ChatController class:
import com.example.chatonline.domain.Mensagem;
import com.example.chatonline.domain.Usuario;
import com.example.chatonline.services.ChatService;
import com.example.chatonline.services.UsuarioService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping(value = "/chat")
public class ChatController {
#Autowired
private ChatService chatService;
#Autowired
UsuarioService usuarioService;
#PreAuthorize("isAuthenticated()")
#GetMapping(value = "/usuarios")
public ResponseEntity<List<Usuario>> findOnlineUsers(){
List<Usuario> usuarios = usuarioService.findByOnlineUsers();
return ResponseEntity.ok().body(usuarios);
}
#PreAuthorize("isAuthenticated()")
#GetMapping(value = "/mensagens")
public ResponseEntity<List<Mensagem>> findMessages(){
List<Mensagem> obj = chatService.findMessages();
return ResponseEntity.ok().body(obj);
}
#PostMapping
public ResponseEntity<Void> insertMessage(#RequestBody Mensagem obj){
obj = chatService.insertMessage(obj);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
#RequestMapping(value = "/mensagens/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteMessage(#PathVariable Integer id){
chatService.deleteMessage(id);
return ResponseEntity.noContent().build();
}
}

Postman gives 401 Unauthorized -"spring boot security"

I'm trying to configure Spring Security on a Spring Boot application as follows and as a result Postman gives 401 Unauthorized ,please can anyone help me to solve this error
controller
package com.example.demo.controller;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
#CrossOrigin(origins = "http://localhost:8080")
#RestController
#RequestMapping("/api")
public class UserController {
#Autowired
private UserService userService;
#PostConstruct
public void initRoleAndUser() {
userService.initRoleAndUser();
}
#PostMapping({"/registerNewUser"})
public User registerNewUser(#RequestBody User user) {
return userService.registerNewUser(user);
}
#GetMapping({"/forAdmin"})
#PreAuthorize("hasRole('Admin')")
public String forAdmin(){
return "This URL is only accessible to the admin";
}
#GetMapping({"/forUser"})
#PreAuthorize("hasRole('User')")
public String forUser(){
return "This URL is only accessible to the user";
}
}
configuration
package configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Autowired
private UserDetailsService jwtService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors();
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate", "/registerNewUser").permitAll()
.antMatchers(HttpHeaders.ALLOW).permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(jwtService).passwordEncoder(passwordEncoder());
}
}
JwtService
package com.example.demo.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.example.demo.dao.UserDao;
import com.example.demo.Util.JwtUtil;
import com.example.demo.entity.User;
import com.example.demo.entity.JwtResponse;
import com.example.demo.entity.JwtRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.HashSet;
import java.util.Set;
#Service
public class JwtService implements UserDetailsService {
#Autowired
private JwtUtil jwtUtil;
#Autowired
private UserDao userDao;
private AuthenticationManager authenticationManager;
public JwtResponse createJwtToken(JwtRequest jwtRequest) throws Exception {
String userName = jwtRequest.getName();
String userPassword = jwtRequest.getUser_code();
authenticate(userName, userPassword);
UserDetails userDetails = loadUserByUsername(userName);
String newGeneratedToken = jwtUtil.generateToken(userDetails);
User user = userDao.findById(userName).get();
return new JwtResponse(user, newGeneratedToken);
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findById(username).get();
if (user != null) {
return new org.springframework.security.core.userdetails.User(
user.getName(),
user.getUser_code(),
getAuthority(user)
);
} else {
throw new UsernameNotFoundException("User not found with username: " + username);
}
}
private Set getAuthority(User user) {
Set<SimpleGrantedAuthority> authorities = new HashSet<>();
user.getRoles().forEach(role -> {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
});
return authorities;
}
private void authenticate(String userName, String userPassword) throws Exception {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName, userPassword));
} catch (DisabledException e) {
throw new Exception("USER_DISABLED");
} catch (BadCredentialsException e) {
throw new Exception("INVALID_CREDENTIALS");
}
}
}
I use postman to test and when I do a GET to "http://localhost:8080/forAdmin", I get an error 401 Unauthorized
You must load the user into memory from the database, and it should be converted to UserDetails. The user details has Roles, or Authorities. It dependes what you choose. Maybe these articles can help :)
https://www.baeldung.com/spring-security-authentication-with-a-database
https://www.baeldung.com/role-and-privilege-for-spring-security-registration

Spring security , Principal returns null

i am tryig to post an object to the database using postman , the token generated corectlly but the principal is null !? why
in the controller I have the following code .
and the error as shown
the principal tostring is : UsernamePasswordAuthenticationToken [Principal=com.accessjobs.pjp.domain.User#1a1e348b, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[]]
: the principal getName is : null
#RestController
#RequestMapping("/api/job")
#CrossOrigin //to hit the backend server when connect from the frontend server
public class JobController {
Logger logger = LoggerFactory.getLogger(JobController.class);
#Autowired
private JobService jobService;
#Autowired
private MapValidationErrorsService mapValidationErrorsService;
//#valid annotation to validate the object attributes and , i used the following code FieldErrors to display the list of errors from validation
#PostMapping("")
#CrossOrigin
public ResponseEntity<?> add(#Valid #RequestBody Job job, BindingResult result, Principal principal) {
ResponseEntity<?> errorMap = mapValidationErrorsService.MapValidationService(result);
if (errorMap != null) return errorMap;
logger.info("the principal tostring is : "+principal.toString());
logger.info("the principal getName is : "+principal.getName());
Job tempJob = jobService.add(job, principal.getName());
return new ResponseEntity<Job>(tempJob, HttpStatus.CREATED);
}
and the service job code as shown , always give me a null user and catch the error .
that because the email is null.
what is the solution>?
import com.accessjobs.pjp.domain.Job;
import com.accessjobs.pjp.domain.User;
import com.accessjobs.pjp.exceptions.JobIdException;
import com.accessjobs.pjp.repositories.JobRepository;
import com.accessjobs.pjp.repositories.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Locale;
#Service
public class JobService {
Logger logger = LoggerFactory.getLogger(JobService.class);
#Autowired
private JobRepository jobRepository;
#Autowired
private UserRepository userRepository;
public Job add(Job job,String email){
//logic , validation and handling
try {
logger.info("email .is"+email);
User user = userRepository.findByEmail(email);
logger.info("user is ::"+user.toString());
job.setUser(user);
logger.warn(user.getEmail());
job.setUserRole(user.getRole());
logger.info(user.getRole());
//convert the identifier to upper case
job.setJobIdentifier(job.getJobIdentifier().toUpperCase(Locale.ROOT));
return jobRepository.save(job);
}catch (Exception e){
throw new JobIdException("Job Identifier '"+job.getJobIdentifier().toUpperCase(Locale.ROOT)+"' already exists");
}
}
package com.accessjobs.pjp.services;
import com.accessjobs.pjp.domain.User;
import com.accessjobs.pjp.exceptions.EmailAlreadyExistsException;
import com.accessjobs.pjp.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
#Autowired //define the bean in the main spring boot app
private BCryptPasswordEncoder bCryptPasswordEncoder;//store non readable password in the database
public User register(User newUser){
try{
newUser.setPassword(bCryptPasswordEncoder.encode(newUser.getPassword()));
//user name has to be unique (exception)
newUser.setEmail(newUser.getEmail());
//make sure that pass and confpass are matches
//we dont presist or show the confirm password
newUser.setConfirmPassword("");
return userRepository.save(newUser);
}catch (Exception e){
throw new EmailAlreadyExistsException("Email' "+newUser.getEmail()+"' is already exists");
}
}
}
maybe the error in the database , how can I permit all URLs for the MySQL database
this is the class that implements the user detailsservice
package com.accessjobs.pjp.services;
import com.accessjobs.pjp.domain.User;
import com.accessjobs.pjp.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userRepository.findByEmail(email);
if(user==null) new UsernameNotFoundException("User not found");
return user;
}
#Transactional
public User loadUserById(Long id){
User user = userRepository.getById(id);
if(user==null) new UsernameNotFoundException("User not found");
return user;
}
}
is there any errors in this class ?
especially in the MySQL permissions and antMatchers?
package com.accessjobs.pjp.security;
import com.accessjobs.pjp.services.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import static com.accessjobs.pjp.security.SecurityConstants.*;
//video rep branch 65
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(customUserDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Override
#Bean(BeanIds.AUTHENTICATION_MANAGER)
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// .and().headers().frameOptions().sameOrigin() //To enable H2 Database
.and()
.authorizeRequests()
.antMatchers(
"/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
.antMatchers("/api/users/**").permitAll()
.antMatchers(SIGN_UP_URLS).permitAll()
.antMatchers("jdbc:mysql://localhost:3306/").permitAll()**//here ?**
.antMatchers("/api/users/**").permitAll()
.antMatchers("/api/users/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
Make sure your token has a sub property. Use this tool to post the contents of your token (minus any secure properties).
https://jwt.io/

Field jwtFilter required a bean of type 'filter.JwtFilter' that could not be found.?

I want to start my spring app after i made some jwt authentification configuration. but i have this issues :
Description:
Field jwtFilter in com.soheibKehal.CashApi.config.SecurityConfig required a bean of type 'filter.JwtFilter' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'filter.JwtFilter' in your configuration.
The thing is in my SecurityConfig class, i already Beaned my AuthentificationManager method, so i dont know what is the problem ?
package com.soheibKehal.CashApi.config;
import com.soheibKehal.CashApi.services.CustomUserDetailService;
import filter.JwtFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailService userDetailsService;
#Autowired
private JwtFilter jwtFilter;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
#Bean(name = BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/authenticate")
.permitAll().anyRequest().authenticated()
.and().exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);;
}
}
my jwtFilter class :
package filter;
import com.soheibKehal.CashApi.Util.JwtUtil;
import com.soheibKehal.CashApi.services.CustomUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class JwtFilter extends OncePerRequestFilter {
#Autowired
private JwtUtil jwtUtil;
#Autowired
private CustomUserDetailService service;
#Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException, IOException, ServletException {
String authorizationHeader = httpServletRequest.getHeader("Authorization");
String token = null;
String userName = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
token = authorizationHeader.substring(7);
userName = jwtUtil.extractUsername(token);
}
if (userName != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = service.loadUserByUsername(userName);
if (jwtUtil.validateToken(token, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
Do you have any idea what is the problem ?
I think the problem is in your package structure. Springboot will scan your app for autoconfiguration starting from the package where you have a class of this structure
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
It should be in the package com.soheibKehal.CashApi.
The solution will be to move the filter package into the com.soheibKehal.CashApi just beside your config package.
Then spring will be able to locate the JwtFilter for autoconfiguration.

Categories

Resources