Прежде всего, вот моя Spring Security Configuration
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
AccountDetailsService accountDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(accountDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http
.authorizeRequests()
.antMatchers("/api/getalltopics").hasRole("ADMIN")
.antMatchers(HttpMethod.POST,"/api/createtopic").hasRole("ADMIN")
.antMatchers("/me").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers("/getcsrftoken").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("http://192.168.1.105:3000/", true)
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("http://192.168.1.105:3000/")
.deleteCookies("JSESSIONID");
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
//This is the password encoder that I will be using
return new BCryptPasswordEncoder();
}
}
, которая ведет меня прямо в мой AccountDetailsService
@Service("userDetailsService")
@Transactional
public class AccountDetailsService implements UserDetailsService {
@Autowired
AccountService accountService;
@Override
public UserDetails loadUserByUsername(String username){
Account account = accountService.findAccountByUsername(username);
//TODO: Check if user exists
return new org.springframework.security.core.userdetails.User(
account.getUsername(), account.getPassword(),
account.isEnabled(), true, true, true,
accountService.getAuthorities(account.getRoles()));
}
}
, который снова приводит меня к моей учетной записи Service
@Service
public class AccountService {
@Autowired
AccountRepository accountRepository;
@Autowired
PrivilegeRepository privilegeRepository;
@Autowired
RoleRepository roleRepository;
public Privilege findPrivilegeByName(String privilegeName){
return privilegeRepository.findByName(privilegeName);
}
public void savePrivilege(Privilege privilege){
privilegeRepository.save(privilege);
}
public Role findRoleByName(String roleName){
return roleRepository.findByName(roleName);
}
public void saveRole(Role role){
roleRepository.save(role);
}
public void saveAccount(Account account){
accountRepository.save(account);
}
public Account findAccountByUsername(String username){
return accountRepository.findByUsername(username);
}
public Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles){
return getGrantedAuthorities(getPrivileges(roles));
}
private List<String> getPrivileges(Collection<Role> roles){
List<String> privileges = new ArrayList<>();
List<Privilege> collection = new ArrayList<>();
for(Role role : roles){
collection.addAll(role.getPrivileges());
}
for(Privilege item : collection){
privileges.add(item.getName());
}
return privileges;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges){
List<GrantedAuthority> authorities = new ArrayList<>();
for (String privilege : privileges){
authorities.add(new SimpleGrantedAuthority(privilege));
}
return authorities;
}
}
А вот и моя сущность Аккаунта на всякий случай, когда это необходимо
@Entity
@Table(name="account")
public class Account extends TimeStampModel{
// Extends TimeStampModel so we know when the user was created
@Id
@GeneratedValue
@Column
private Long id;
@Column(nullable = false)
private String username;
@Column(nullable = false)
private String password;
@Column
private int amountOfLikes;
@Column
private int amountOfDislikes;
@OneToMany(cascade = CascadeType.ALL)
private List<Comment> comments;
@OneToMany(cascade = CascadeType.ALL)
private List<Post> posts;
private boolean isEnabled;
private boolean isTokenExpired;
@ManyToMany
@JoinTable(
name = "account_roles",
joinColumns = @JoinColumn(
name = "account_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles;
public Account(){}
public Account(String username, String password, boolean isEnabled){
this.username = username;
this.password = password;
this.amountOfDislikes = 0;
this.amountOfLikes = 0;
this.isEnabled = isEnabled;
}
//getters and setters omitted
}
Теперь моя проблема в том, что когда я создаю тестового пользователя и назначаю ему роль ADMIN, а позже я пытаюсь проверить, У пользователя есть роль, которую мне всегда возвращают ложным. Если я пытаюсь сделать несколько запросов на мой сервер с пользователем, я всегда получаю 403 Запрещено. Что я здесь не так делаю?
Вот мой класс, где я настроил тестового пользователя, и это тот пользователь, которого я использую, чтобы попытаться войти в систему
@Component
public class InitialDataLoader implements ApplicationListener<ContextRefreshedEvent> {
boolean alreadySetup = false;
@Autowired
AccountService accountService;
@Autowired
PasswordEncoder passwordEncoder;
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent event){
//don't do any setup if it has already been done
if(alreadySetup) return;
Privilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE");
Privilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE");
List<Privilege> adminPrivileges = Arrays.asList(readPrivilege, writePrivilege);
List<Privilege> userPrivileges = Arrays.asList(readPrivilege);
createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
createRoleIfNotFound("ROLE_USER", userPrivileges);
Role adminRole = accountService.findRoleByName("ROLE_ADMIN");
Account account = new Account("test", passwordEncoder.encode("123"), true);
account.setRoles(Arrays.asList(adminRole));
accountService.saveAccount(account);
alreadySetup = true;
}
@Transactional
Privilege createPrivilegeIfNotFound(String privilegeName){
Privilege privilege = accountService.findPrivilegeByName(privilegeName);
if(privilege == null){
//if the privilege doesn't exist, we create one
privilege = new Privilege(privilegeName);
accountService.savePrivilege(privilege);
}
//if the privilege exists, just return it
return privilege;
}
@Transactional
Role createRoleIfNotFound(String roleName, Collection<Privilege> privilegeCollection){
Role role = accountService.findRoleByName(roleName);
if(role == null){
//if the role doesn't exist, we create one
role = new Role(roleName);
role.setPrivileges(privilegeCollection);
accountService.saveRole(role);
}
//if the role exists, just return it
return role;
}
}
Также у меня есть это отображение установить, кто проверяет, есть ли у пользователя какую-то роль, и они всегда возвращают false, если это помогает.
@GetMapping("/me")
public Principal getMe(SecurityContextHolderAwareRequestWrapper requestWrapper, Principal principal) {
System.out.println(requestWrapper.isUserInRole("ADMIN"));
System.out.println(requestWrapper.isUserInRole("ROLE_ADMIN"));
return principal;
}
Я просто не знаю, что делать дальше, я так потерян ..