我想启用管理员访问管理页面并执行管理员工作,但是当我尝试通过设置带有/ admin / **的网址只能由具有角色admin的用户访问时,它会返回403 Forbidden,拒绝访问。但是用户已将权限设置为ROLE_ADMIN我已检查过。我做错了什么?
我的用户登录控制器
@RestController
public class UserController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthorityService authorityService;
@Autowired
private UserAuthorityService userAuthorityService;
@Autowired
TokenUtils tokenUtils;
@Autowired
private UserService userService;
@RequestMapping(value = "/api/login", method = RequestMethod.POST, produces = "text/html")
public ResponseEntity<String> login(@RequestBody LoginDTO loginDTO) {
try {
// System.out.println(loginDTO.getUsername() + " " + loginDTO.getPassword());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
loginDTO.getUsername(), loginDTO.getPassword());
Authentication authentication = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
UserDetails details = userDetailsService.loadUserByUsername(loginDTO.getUsername());
return new ResponseEntity<String>(tokenUtils.generateToken(details), HttpStatus.OK);
} catch (Exception ex) {
return new ResponseEntity<String>("Invalid login", HttpStatus.BAD_REQUEST);
}
}
@RequestMapping(value = "/api/register", method = RequestMethod.POST, produces = "text/html")
public ResponseEntity<String> register(@RequestBody RegisterDTO registerDTO) {
try {
System.out.println(registerDTO);
User user = userService.findUserByUsername(registerDTO.getUsername());
// // Check if user with that username exists
if(user != null){
// User with that username is found
return new ResponseEntity<String>("User with that username exists", HttpStatus.BAD_REQUEST);
}
// We need to save the user so his ID is generated
User newUser = userService.saveUser(new User(registerDTO));
UserAuthority userAuthority = userAuthorityService.save(new UserAuthority(newUser, authorityService.findOneByName("User")));
Set<UserAuthority> authorities = new HashSet<>();
authorities.add(userAuthority);
newUser.setUserAuthorities(authorities);
User savedUser = userService.save(newUser);
return new ResponseEntity<String>("You have registered successfully with username " + savedUser.getUsername(), HttpStatus.OK);
} catch (Exception ex) {
return new ResponseEntity<String>("Invalid register", HttpStatus.BAD_REQUEST);
}
}
}
我可以说我用邮递员测试我的应用程序并且登录和注册工作正常。当用户登录时,我可以使用正确的数据和用户权限,但为什么当我尝试访问/ admin / building / add url时,它返回403错误?
我的控制器,用于为管理页面添加构建:
@RestController
public class BuildingController {
@Autowired
private BuildingService buildingService;
@RequestMapping(value = "/admin/building/add", method = RequestMethod.POST, produces = "text/html")
public ResponseEntity<String> addBuilding(@RequestBody BuildingDTO buildingDTO) {
try{
Building newBuilding = new Building(buildingDTO);
return new ResponseEntity<String>(newBuilding.getName(), HttpStatus.OK);
}catch (Exception ex) {
return new ResponseEntity<String>("Data was not valid", HttpStatus.BAD_REQUEST);
}
}
}
My SecurityConfiguration.java
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configureAuthentication(
AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder
.userDetailsService(this.userDetailsService).passwordEncoder(
passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public AuthenticationTokenFilter authenticationTokenFilterBean()
throws Exception {
AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();
authenticationTokenFilter
.setAuthenticationManager(authenticationManagerBean());
return authenticationTokenFilter;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/index.html", "/view/**", "/app/**", "/", "/api/login", "/api/register").permitAll()
// defined Admin only API area
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
.and().csrf().disable();
//if we use AngularJS on client side
// .and().csrf().csrfTokenRepository(csrfTokenRepository());
//add filter for adding CSRF token in the request
httpSecurity.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
// Custom JWT based authentication
httpSecurity.addFilterBefore(authenticationTokenFilterBean(),
UsernamePasswordAuthenticationFilter.class);
}
/**
* If we use AngularJS as a client application, it will send CSRF token using
* name X-XSRF token. We have to tell Spring to expect this name instead of
* X-CSRF-TOKEN (which is default one)
* @return
*/
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
我应该提一下,我正在使用Angularjs作为前端,但即使这样我也可以登录并为该用户显示正确的权限。但由于某种原因,我无法访问管理页面,即使我以管理员身份登录。
此外,我尝试了.hasAuthority("ROLE_ADMIN")
和.hasRole("ROLE_ADMIN")
(显示ROLE_的错误),因此我将其更改为.hasRole("ADMIN")
,但仍然无效。
在数据库中,admin的角色保存为ROLE_ADMIN。
答案 0 :(得分:8)
答案 1 :(得分:0)
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();// We don't need sessions to be created.
}
}
这为我做到了。现在,我可以成功提交我的发帖请求了
答案 2 :(得分:0)
在SecurityConfig中尝试一下:
.antMatchers("/api/admin").access("hasRole('ADMIN')")
.antMatchers("/api/user").access("hasRole('ADMIN') or hasRole('USER')")