Да, я знаю, что этот вопрос уже задан. Но по этому вопросу у меня тоже другая проблема. AuthenticationManager объекта AuthenticationManager в классе SecurityServiceImpl, который не аутентифицирует детали, из-за которых я застрял на этом этапе.
Я пытался дать сообщение после каждого шага, с помощью которого я могу отслеживать конкретный код, работают они или нет, и я обнаружил в классе SecurityServiceImpl, что он не работает после этого кода
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
Не знаю, это просто мое понимание. Помогите мне решить эту проблему и сообщите, есть ли у вас лучший фрагмент кода для решения этой конкретной проблемы.
Безопасность Конфигурация
package com.demo.practice.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
@Autowired
private UserDetailsService userDetailsService;
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/register","/login").permitAll()
.antMatchers("/student/**").hasAuthority("STUDENT")
.antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.defaultSuccessUrl("/dashboard");
http.csrf().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
UserServiceImpl
package com.demo.practice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.demo.practice.model.Credentials;
import com.demo.practice.model.Role;
import com.demo.practice.model.User;
import com.demo.practice.repository.UserRepository;
@Service
public class UserServiceImpl implements UserServiceInterface {
@Autowired
private BCryptPasswordEncoder encoder;
@Autowired
UserRepository userRepo;
@Override
public void saveUser(User user,Credentials credential) {
user.setCredential(credential);
user.getCredential().setUsername(user.getEmail());
user.getCredential().setRoles(Role.STUDENT);
user.getCredential().setPassword(encoder.encode(user.getCredential().getPassword()));
userRepo.save(user);
}
@Override
public User findUserByEmail(String name) {
User user=userRepo.findUserByEmail(name);
return user;
}
}
UserDetailsServiceImpl
package com.demo.practice.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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;
import com.demo.practice.model.Credentials;
import com.demo.practice.repository.CredentialRepository;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
CredentialRepository credRepo;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Credentials credential =credRepo.findByUsername(username);
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new SimpleGrantedAuthority(credential.getRoles().toString()));
return new org.springframework.security.core.userdetails.User(credential.getUsername(), credential.getPassword(), grantedAuthorities);
}
}
SecurityServiceImpl
package com.demo.practice.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
@Service
public class SecurityServiceImpl implements SecurityServiceInterface {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class);
@Override
public String findLoggedInUsername() {
Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails();
if (userDetails instanceof UserDetails) {
return ((UserDetails)userDetails).getUsername();
}
return null;
}
@Override
public void autologin(String username, String password) {
System.out.println("in autologin "+username);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
System.out.println("in autologin at userdetails"+userDetails);
logger.info("after userdetails "+userDetails);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(),userDetails.getAuthorities());
logger.info("in autologin after usernamepasswordauthentication! ", usernamePasswordAuthenticationToken);
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
logger.info("after authentication manager ", usernamePasswordAuthenticationToken);
if (usernamePasswordAuthenticationToken.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
logger.debug(String.format("Auto login %s successfully!", username));
}
else System.out.println("auto login failed");
}
}





вам не хватает одной вещи, если вы хотите иметь сеанс аутентификации, вам нужно добавить WebAuthenticationDetails к токену, например:
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(principalUser, null, List.of(new SimpleGrantedAuthority(principalUser.getRole())));
token.setDetails(new WebAuthenticationDetails(request));
SecurityContextHolder.getContext().setAuthentication(token);
WebAuthenticationDetails из документа:
Records the remote address and will also set the session Id if a session already exists (it won't create one).
для получения дополнительной информации о процессе входа / выхода, посмотрите: https://github.com/pezetem/spring-security-angular-skeleton/blob/master/src/main/java/com/pezetem/blog/code/spring_security_custom_authorizers/security/SecurityController.java
ОБНОВИТЬ:
хорошо, может быть другая причина, почему это не работает для вас. Spring Security добавляет к ролям префикс по умолчанию. Равно ROLE_. Это означает, что когда у вас есть конечная точка, настроенная для .hasAuthority("STUDENT"), роль должна быть равна ROLE_STUDENT, взгляните на строку, в которой вы создаете пользователя, вы назначаете роль с Role.STUDENT, а значение перечисления должно быть ROLE_STUDENT, а не STUDENT
место, взгляните на обновленный ответ, может быть проблема с префиксом роли, вам не хватает для Role.STUDENT