Я использую Spring boot 2.1.3
с аутентификацией JWT.
ссылка: https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-2/
@SpringBootApplication
public class LrimspublicApplication extends SpringBootServletInitializer implements CommandLineRunner
{
@Autowired
private PasswordEncoder passwordEncoder;
public static void main(String[] args) {
SpringApplication.run(LrimspublicApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(LrimspublicApplication.class);
}
@Override
public void run(String... args) throws Exception {
System.out.println(passwordEncoder.encode("devil@123"));
}
}
SpringSecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CustomUserDetailsService customUserDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/app/**").permitAll()
.antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
.permitAll()
.antMatchers(HttpMethod.GET, "/api/polls/**", "/api/users/**")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
и теперь я создаю нового пользователя с помощью API post, который выглядит следующим образом:
@RequestMapping(value = "/app/user/create", method = RequestMethod.POST)
@ResponseBody
public Tbluser createUser(HttpServletRequest request, HttpServletResponse response) throws ParseException{
String district="";
String office=null;
String gender="";
String firstName="";
String middleName="";
String lastName="";
String mobileNumber="";
String emailID="";
String dateOfBirth="";
String address="";
String userName="";
String password="";
String employeeId="";
List<Tbluser> users=null;
Tbluser user=new Tbluser();
String encryptedPassword="";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
DateFormat dateformatter = new SimpleDateFormat("dd-MM-yyyy");
Date dt_dateOfBirth = null;
Tblrole role=new Tblrole();
//String userTypeId="Official";
String userTypeId="4";
String active="1";
String description="";
Date createdDate;
String createdBY="";
String userId="";
String newUserRole="";
String secretcode="";
String firstNameNepali="";
String middleNameNepali ="";
String lastNameNepali = "";
try {
try{district = ServletRequestUtils.getRequiredStringParameter(request, "ddlAddUserDistrict");}catch(Exception ex){}
try{office = ServletRequestUtils.getRequiredStringParameter(request, "ddlAddUserOffice");}catch(Exception ex){}
try{gender=ServletRequestUtils.getRequiredStringParameter(request, "ddlAddUserGender");}catch(Exception ex){}
try{firstName=ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserFirstName");}catch(Exception ex){}
try{middleName = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserMiddleName");}catch(Exception ex){}
try{lastName = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserLastName"); }catch(Exception ex){}
try{mobileNumber = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserMobileNumber");}catch(Exception ex){}
try{emailID = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserEmailID"); }catch(Exception ex){}
try{dateOfBirth = ServletRequestUtils.getRequiredStringParameter(request, "hidUserDateOfBirth");}catch(Exception ex){}
try{address = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserAddress"); }catch(Exception ex){}
try{userName = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserName");}catch(Exception ex){}
try{password = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserPassword");}catch(Exception ex){}
try{employeeId = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserEmployeeId");}catch(Exception ex){}
try{secretcode= ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserSecretCode");}catch(Exception ex){}
if (!dateOfBirth.isEmpty() && dateOfBirth!=null)
{
//dt_dateOfBirth = df.parse(dateOfBirth);
dt_dateOfBirth = dateformatter.parse(dateOfBirth);
}
try{description = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserDescription"); }catch(Exception ex){}
try{createdBY= ServletRequestUtils.getRequiredStringParameter(request, "hid-createdBy");}catch(Exception ex){}
try{userId=ServletRequestUtils.getRequiredStringParameter(request, "hid-userId");}catch(Exception ex){}
try{newUserRole=ServletRequestUtils.getRequiredStringParameter(request, "user_roles");}catch(Exception ex){}
try{firstNameNepali=ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserFirstNameNepali");}catch(Exception ex){}
try{middleNameNepali = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserMiddleNameNepali");}catch(Exception ex){}
try{lastNameNepali = ServletRequestUtils.getRequiredStringParameter(request, "txtAddUserUserLastNameNepali");}catch(Exception ex){}
//*To save Biometric and Image data*//*
try{
String imagedata = ServletRequestUtils.getRequiredStringParameter(request, "imagedataForSeller");
String leftthumbimage = ServletRequestUtils.getRequiredStringParameter(request, "hidUserInformationLeftThumbImpressionImage");
String leftthumbdata = ServletRequestUtils.getRequiredStringParameter(request, "hidUserInformationLeftThumbImpressionData");
String rightthumbimage = ServletRequestUtils.getRequiredStringParameter(request, "hidUserInformationRightThumbImpressionImage");
String rightthumbdata = ServletRequestUtils.getRequiredStringParameter(request, "hidUserInformationRightThumbImpressionData");
String signaturedata = ServletRequestUtils.getRequiredStringParameter(request, "hidOldSellerSignatureImage");
if(user.getSignature() == null || user.getSignature().length < 1)
{
signaturedata = ServletRequestUtils.getRequiredStringParameter(request, "hidNewSellerSignatureImage");
}
user.setLeftthumbimpression(org.apache.commons.codec.binary.Base64.decodeBase64(leftthumbimage.getBytes()));
user.setLeftthumbimpressiondata(leftthumbdata.getBytes(Charset.forName("UTF-8")));
user.setRightthumbimpression(org.apache.commons.codec.binary.Base64.decodeBase64(rightthumbimage.getBytes()));
user.setRightthumbimpressiondata(rightthumbdata.getBytes(Charset.forName("UTF-8")));
user.setPhoto(org.apache.commons.codec.binary.Base64.decodeBase64(imagedata.getBytes()));
}
catch(Exception ex){}
try{user.setTbldistrict(districtService.findDistirctById(Long.parseLong(district)));}catch(Exception ex){}
try{user.setTbloffice(officeService.findOfficeById(Long.parseLong(office)));}catch(Exception ex){}
try{user.setTblgender(genderService.findGenderById(Long.parseLong(gender)));}catch(Exception ex){}
try{user.setAddress(address);}catch(Exception ex){}
try{user.setUsername(userName);}catch(Exception ex){}
try{user.setPassword(passwordEncoder.encode(password));}catch (Exception ex){}
role=roleService.findRoleByID(Long.parseLong(newUserRole));
//* Role mapping *//*
Set<Tblrole> roleSet = new HashSet<Tblrole>();
roleSet.add(role);
user.setTblroles(roleSet);
user= userService.saveUser(user);
} catch(Exception ex){
logger.error(ex);
}
return user;
}
Пользователь API создания успешно создает / вставляет пользователя в базу данных.теперь, когда я пытаюсь войти в систему, происходит сбой и выдает неверные учетные данные:
мой контроллер входа
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
//Tbluser user = userRepository.findByUsername(loginRequest.getUsernameOrEmail());
Optional<Tbluser> user = userRepository.findByUsername(loginRequest.getUsernameOrEmail());
Tbluser u = new Tbluser();
if(user.isPresent()){
u = user.get();
}
Tbluser uu =new Tbluser() ;
// UserPojo userPojo =
Map<String ,Object> map = new HashMap<>();
Set<Tblrole> roleList = uu.getTblroles();
SecurityContextHolder.getContext().setAuthentication(authentication);
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
String accessToken = tokenProvider.generateToken(authentication);
String refreshToken = tokenProvider.generateRefreshToken();
//saveRefreshToken(userPrincipal, refreshToken);
StringBuilder builder = new StringBuilder();
String combinedToken =builder.append(accessToken).append(",").append(refreshToken).toString();
return ResponseEntity.ok().header("Authorization",combinedToken).body(map);
}
ОБНОВЛЕНО: -
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String usernameOrEmail)
throws UsernameNotFoundException {
// Let people login with either username or email
Tbluser user = userRepository.findByUsername(usernameOrEmail)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with username or email : " + usernameOrEmail)
);
return UserPrincipal.create(user);
}
@Transactional
public UserDetails loadUserById(Long id) {
Tbluser user = userRepository.findById(id).orElseThrow(
() -> new ResourceNotFoundException("User", "id", id)
);
return UserPrincipal.create(user);
}
}
и UserPrincipal: -
public class UserPrincipal implements UserDetails {
private Long id;
private String name;
private String username;
@JsonIgnore
private String email;
@JsonIgnore
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserPrincipal(Long id, String name, String username, String email, String password, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.name = name;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static UserPrincipal create(Tbluser user) {
List<GrantedAuthority> authorities = user.getTblroles().stream().map(role ->
new SimpleGrantedAuthority(role.getRolename())
).collect(Collectors.toList());
return new UserPrincipal(
user.getUserid(),
user.getFirstname(),
user.getUsername(),
user.getEmailid(),
user.getPassword(),
authorities
);
}
//getter setter excluded
}
Теперь интересной частью является то, что всякий раз, когда я заменяю свой пароль в базе данных на пароль, сгенерированный на консоли (из реализации commandlinerunner), он успешно генерирует токен.
и теперь, когда я вижу / app /создать / пользователя API для создания пользователя я не вижу ничего плохого в создании пользователя.
что я пропустил?указание на ошибку действительно поможет мне.