Я интегрировал role
и хочу управлять доступом к определенной службе на основе роли.Администратор может создать АГЕНТ , и этот агент входит в группу пользователей ADMIN.
То, что я в основном сделал, создало корабль отношений 1 to Many
, потому что мой пользователь мог иметь только 1 роль.
@Entity
@Table(name = "role")
public class Role {
private Long id;
private String name;
private Collection<User> users;
public Role() {
}
public Role(String name) {
this.name = name;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
}
И здесь у меня есть пользователь, для которого отношение группы, а также группа также 1 TO MANY
, потому что user_admin может иметь несколько агентов, но агент не может иметь несколько администраторов.
@Entity
@Table(name = "user")
public class User {
private long id;
private String username;
private String password;
private boolean enabled = false;
private Role role;
private UserGroup userGroup;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(String username, String password, Role role) {
this.username = username;
this.password = password;
this.role = role;
}
public User(String username, String password, boolean enabled, Role role, UserGroup userGroup) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.role = role;
this.userGroup = userGroup;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@NotBlank
@Column(nullable = false, updatable = false, unique = true)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@NotBlank
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(nullable = false, updatable = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@ManyToOne
@JoinColumn(name = "role_id", referencedColumnName = "id")
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@ManyToOne
@JoinColumn(name = "user_group_id", referencedColumnName = "id")
public UserGroup getUserGroup() {
return userGroup;
}
public void setUserGroup(UserGroup userGroup) {
this.userGroup = userGroup;
}
}
Во время создания пользователя я указываю также роль и группу.
И в SecurityConfig
я настраиваю вот так.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(Constants.BASE_URL_FILE_UPLOADER + Constants.URL_UPLOAD_FILE).hasRole("ADMIN") .anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.exceptionHandling().authenticationEntryPoint(new ContentSearcherAuthenticationEntryPoint());
}
Но если яя получаю доступ к этой конечной точке с помощью администратора, который я выбрасываю запрещено , а также в функцию, когда я получаю доступ к authentication.getAuthorities()
, он возвращает emptyList
ResponseEntity<JsonNode> uploadFile(@RequestParam("file") MultipartFile file, Authentication authentication) {
logger.info("Authentication is [{}] and user is [{}]", authentication.getAuthorities(), authentication.getName()); // []
}
Язапутался в UserDetailsService
Я также добавил GrantedAuthority
так же, как это.
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private UserRepository userRepository;
private RoleRepository roleRepository;
public UserDetailsServiceImpl(UserRepository userRepository, RoleRepository roleRepository) {
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username + " Not Exists");
}
user.setEnabled(true);
userRepository.save(user);
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.isEnabled(),
true, true, true, getAuthorities(user.getRole()));
}
private Collection<? extends GrantedAuthority> getAuthorities(
Role role) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(Constants.ROLE_PREFIX + role.getName()));
return authorities;
}
}
Чего мне не хватает, есть ли еще конфигурация, которую я должен добавить?
Я используюJWT для целей аутентификации не нужно добавлять что-то вэто также?
Потому что, когда я получаю Authentication
в JWT successfulAuthentication
, он показывает полномочия.
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
logger.info("Auth in the successful is [{}]", authResult.getAuthorities()); // [ROLE_ADMIN]
}
Использование ядра Spring-Security 5.0.9.