我使用的是Spring Security 3我的目标是基于角色和权限授予特定用户特定的操作(控制器方法)。
ROLE_ADMIN ->创建、读取、更新和删除ROLE_USER ->读取和更新。
当我注册一个用户时,它会作为一个用户对象保存到一个数据库中,密码加密,没有问题。但是当我使用UserController
和Postman的基本身份验证来访问控制器API时,它显示状态200 OK,但不是预期的JSON输出。然后在面对,当我击中相同的网址与谷歌Chrome,它是显示白标签错误页面与状态404未找到。
这里是我的SecurityConfig.java
@Configuration
//@Import({GsonConfig.class})
@EnableMethodSecurity
@EnableWebSecurity(debug = true)
public class SecurityConfig {
@Autowired
ProductUserRepository productuserrepo;
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return username -> productuserrepo.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(csrf -> csrf.disable())
.cors(cors -> cors.disable())
.authorizeHttpRequests(a -> {
a.requestMatchers("/auth/**").permitAll();
a.anyRequest().authenticated();
})
.formLogin(login -> {
login.loginProcessingUrl("/login")
.failureForwardUrl("/loginfailure");
})
.logout(logout ->{
logout.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(false)
.logoutSuccessUrl("/successlogout")
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
})
.authenticationManager(authManager())
.build();
}
@Bean
public AuthenticationManager authManager(){
DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
daoProvider.setUserDetailsService(userDetailsService());
daoProvider.setPasswordEncoder(encoder());
return new ProviderManager(daoProvider);
}
}
这是我的Role.java [使用List<SimpleGrantedAuthority>
获取权限列表]
@RequiredArgsConstructor
public enum Role {
USER(Set.of(USER_READ,USER_UPDATE)),
ADMIN(Set.of(ADMIN_READ,ADMIN_UPDATE,ADMIN_DELETE,ADMIN_CREATE,
USER_READ,USER_UPDATE));
@Getter
private final Set<Permission> permissions;
public List<SimpleGrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> authorities = getPermissions().stream()
.map(permission -> new SimpleGrantedAuthority(permission.getPermission()))
.collect(Collectors.toList());
authorities.add(new SimpleGrantedAuthority("ROLE_" + this.name()));
return authorities;
}
}
这里是我的Permission.java
public enum Permission {
ADMIN_READ("admin:read"),
ADMIN_UPDATE("admin:update"),
ADMIN_CREATE("admin:create"),
ADMIN_DELETE("admin:delete"),
USER_READ("user:read"),
USER_UPDATE("user:update");
@Getter
private final String permission;
}
最后这里是我的用户控制器读取资源
@RestController
@RequestMapping("/user")
@PreAuthorize("hasAnyRole('USER','ADMIN')")
public class UserController {
@PreAuthorize("hasAnyAuthority('admin:read','user:read')")
@GetMapping(value = "/findproduct",produces = MediaType.APPLICATION_JSON_VALUE,
headers = "Accept=application/json",consumes = MediaType.APPLICATION_JSON_VALUE)
public Product findproductbyid(@RequestParam("productid")int productid) {
System.out.println("inside findproduct method");
return prodrepo.findById(productid).get();
}
}
和我的AuthController注册:
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
ProductUserRepository produserrepo;
@Autowired
PasswordEncoder pwd_encoder;
@Autowired
Gson gson;
@PostMapping(value = "/register",produces = MediaType.APPLICATION_JSON_VALUE,
headers = "Accept=application/json",consumes = MediaType.APPLICATION_JSON_VALUE)
public String register(@RequestBody ProductUserModel user) {
if (produserrepo.existsByUsername(user.getUsername())) {
return user.getUsername() + " already taken";
}else {
System.out.println(user.toString());
user.setPassword(pwd_encoder.encode(user.getPassword()));
produserrepo.save(gson.fromJson(gson.toJson(user), ProductUser.class));
return user.getUsername() + " succesfully registered";
}
}
我唯一的问题是:当我使用Google Chrome为UserController
点击http://localhost:8081/user/findproduct?productid=1
时,登录页面重定向。然后,如果我击中用户名/密码凭据,我成功地注册并保存到数据库,它显示白标签错误页面状态404未找到。
有没有人有办法解决这个问题?
1条答案
按热度按时间yduiuuwa1#
好吧,我自己解决。
首先,我在AuthController中添加了登录方法
其次,我在安全配置类中将/login更改为auth/login
谢意和真挚的问候