2017-11-10 14 views
-1

admin 페이지에 액세스하고 admin 작업을 수행 할 수있게하려고하지만,/admin/**을 사용하여 url을 사용자 만 액세스 할 수 있도록 설정하여이를 수행하려고 할 때 역할 admin으로 403 Forbidden을 반환하고 액세스가 거부되었습니다. 그러나 사용자는 내가 선택한 ROLE_ADMIN으로 권한을 설정했습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 사용자 로그인스프링 보안 항상 403 반환 금지, 액세스가 거부되었습니다.

내 컨트롤러

@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/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); 
     } 
    } 
} 

내 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으로 저장됩니다. 이 같은

+1

당신은 완전히 당신의 로그인으로 봄 보안을 우회하고 있습니다. 로그인을 처리하기 위해 스프링 보안을 사용하여 자신 만의 재창조를하지 마십시오. –

답변

1

시도해보십시오 COMPLET 구성 예를 들어

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.HttpMethod; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.config.http.SessionCreationPolicy; 

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    private static String REALM="MY_TEST_REALM"; 

    @Autowired 
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("ADMIN"); 
     auth.inMemoryAuthentication().withUser("tom").password("abc123").roles("USER"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.csrf().disable() 
     .authorizeRequests() 
     .antMatchers("/user/**").hasRole("ADMIN") 
     .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()) 
     .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created. 
    } 

    @Bean 
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){ 
     return new CustomBasicAuthenticationEntryPoint(); 
    } 

    /* To allow Pre-flight [OPTIONS] request from browser */ 
    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**"); 
    } 
} 

: Secure Spring REST API using Basic Authentication