Сбой аутентификации JWT: неверные учетные данные

#java #spring-boot #spring-security

#java #весенняя загрузка #spring-безопасность

Вопрос:

Я использую 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);

    }
  

и теперь я создаю нового пользователя, используя post API, который выглядит следующим образом

 @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() amp;amp; 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;

    }
  

The user create api successfully creates/inserts the user into database. now when i try to login it fails and says bad credentials:

my login controller is

 @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);
    }
  

UPDATED:-

 @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 / create / user api для создания пользователя, я не вижу ничего плохого в создании пользователя.

чего мне не хватало? указание на ошибку действительно окажет мне огромную помощь.

Комментарии:

1. Пожалуйста, покажите код вашего класса CustomUserDetailsService.

2. пожалуйста, проверьте еще раз. я обновил сообщение.

3. у вас есть пользовательский AuthenticationProvider? В противном случае Spring использует AnonymousAuthenticationProvider.

4. нет, нет какого-либо пользовательского поставщика аутентификации.

5. // Добавьте наш пользовательский фильтр безопасности JWT http.addFilterAfter(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class ); // он вернет HttpSecurity для дальнейших настроек