spring - SpringSecurity configure() 方法配置问题
问题描述
我开发了一个 REST api,其中使用 SpringSecurity 保护方法。
GitHub 链接->项目
它正在工作,但不如预期
SpringSecurity.config
---------------
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsService userDetailService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(encode());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable();
http
.authorizeRequests()
.antMatchers("/user/**")
.authenticated()
.anyRequest()
.hasAnyRole("USER","ADMIN")
.and()
.authorizeRequests()
.antMatchers("/admin/**")
.authenticated()
.anyRequest()
.hasRole("ADMIN")
.and()
.formLogin()
.permitAll();
/*http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER","ADMIN")
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll();*/
}
@Bean
public BCryptPasswordEncoder encode() {
return new BCryptPasswordEncoder();
}
}
AdminController
----------
@RestController
@RequestMapping("/admin")
public class AdminController {
@Autowired
private UserRepo userRepo;
@Autowired
private BCryptPasswordEncoder encoder;
@PostMapping("/add")
@PreAuthorize("hasRole('ADMIN')")
public String addUser(@RequestBody User user) {
String encodedPwd= encoder.encode(user.getPassword());
user.setPassword(encodedPwd);
userRepo.save(user);
return "user added sucessfully...";
}
@GetMapping("/demo")
@PreAuthorize("hasRole('ADMIN')")
public String getDemo() {
return "Hi";
}
}
自定义控制器
--------------
@RestController
@RequestMapping("/user")
public class CustomController {
@GetMapping("/access")
@PreAuthorize("hasAnyRole('USER','ADMIN')")
public String showUser() {
return "Url Security Provided";
}
}
CustomUserDetailService
--------------
@Service
public class CustomUserDetailService implements UserDetailsService {
@Autowired
private UserRepo userRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user= userRepo.findByUsername(username);
CustomUserDetails userDetails= null;
if(user!= null) {
userDetails= new CustomUserDetails();
userDetails.setUser(user);
}else {
throw new UsernameNotFoundException("User Not Found");
}
return userDetails;
}
}
自定义用户详细信息 -----------------
@Getter
@Setter
public class CustomUserDetails implements UserDetails {
/**
*
*/
private static final long serialVersionUID = 1L;
private User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
/*return user.getRoles().stream()
.map(role->new SimpleGrantedAuthority("ROLE_"+ role))
.collect(Collectors.toList());*/
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return user.getPassword();
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
public CustomUserDetails() {
super();
// TODO Auto-generated constructor stub
}
}
用户
----------
@Entity
@Getter
@Setter
@NoArgsConstructor
public class User {
@Id
@GenericGenerator(name="gen",strategy="increment")
@GeneratedValue(generator="gen")
private int user_id;
private String username;
private String password;
private String email;
@OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
@JoinTable(name="user_roles",
joinColumns= @JoinColumn(referencedColumnName= "user_id"),
inverseJoinColumns= @JoinColumn(referencedColumnName="role_id"))
private Set<Roles> roles;
}
问题是:通过上述设置,我可以访问用户而不是管理员的 URL
如果我在评论
http
/*.authorizeRequests()
.antMatchers("/user/**")
.authenticated()
.anyRequest()
.hasRole("USER")
.and()*/
.authorizeRequests()
.antMatchers("/admin/**")
.authenticated()
.anyRequest()
.hasRole("ADMIN")
.and()
.formLogin()
.permitAll();
然后我可以访问用于ADMIN的URL ,但我缺少对USER的URL的身份验证
同样,如果我在评论admin/则可以访问USER部分。它的行为就像 Ordering 哪个 url 第一个是它识别出的,第二个只是在浏览器中给出 403 而不是在控制台中给出任何东西。
类似于 Order 之类的东西,首先可以访问
有没有我做错的地方。
如果我不发表评论@EnableGlobalSecurity
,@PreAuthorize
我将无法访问任何用于ADMIN和USER的URL ,所以我不能错过,因为这些是用于保护 REST API 方法的403
@EnableGlobalSecurity
@PreAuthorize
解决方案
只需为您的管理员角色添加对所有页面的权限。这样,您可以确保您的管理员可以访问他想要的任何页面。
http
/*.authorizeRequests()
.antMatchers("/user/**")
.authenticated()
.anyRequest()
.hasRole("USER")
.and()*/
.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/user/**")
.hasAnyRole("ADMIN", "USER")
.and()
.formLogin()
.permitAll();
推荐阅读
- python - Python Segmentation Fault - 在 Eclipse 中运行时未观察到
- kubernetes - etcdctl 快照状态无法获取存储桶的静音
- csv - 是否可以在不知道每列的宽度或列名并将其转换为 CSV 的情况下解析固定宽度的文件?
- java - 解析邀请并获取公会ID
- python - 删除不满足特定方程条件的行,但具有 NaN 的行除外
- flask - GraphQL 查询返回 null:flask-graphene
- ssis - 将 SSIS 连接到 Heroku PostgreSQL 数据库
- python-camelot - 如何使用 tabula_py 或 camelot 读取分布在多个页面上的表格
- django - 无法在迁移中创建对象
- apache-spark - 停止特定的火花动作