我已经集成了role
,并希望根据角色来管理特定服务的访问。
管理员可以创建一个代理,并且该代理位于ADMIN用户组之下。
我基本上创建了一个1 to Many
关系飞船,因为我的用户只能拥有一个角色。
@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 < / p>
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进行身份验证,因此也应该在其中添加一些内容吗?
因为当我在JWT Authentication
中获得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。
答案 0 :(得分:0)
我从@Reza Nasiri问题获得提示后就做到了,基本上我现在所做的是在认证Authorities
令牌时没有添加JWT
return new UsernamePasswordAuthenticationToken(user, null, getAuthorities("ADMIN");
在我的getAuthentication
类的JWTAuthorizationFilter
函数中。