#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 для дальнейших настроек