복붙노트

[SPRING] 특정 URL에 대해 봄 보안을 사용 중지하는 방법

SPRING

특정 URL에 대해 봄 보안을 사용 중지하는 방법

나는 상태가없는 봄 보안을 사용하고 있지만 가입의 경우 나는 봄 보안을 비활성화하고 싶다.

antMatchers("/api/v1/signup").permitAll().

하지만 작동하지 않는, 내가 아래 오류가 점점 :

 message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException

나는 스프링 보안 필터가 작동하고 있다는 것을 의미한다고 생각한다.

내 URL의 순서는 항상 "/ api / v1"이됩니다.

내 봄 설정은 다음과 같습니다.

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

         http.
         csrf().disable().
         sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
         and().
         authorizeRequests().
         antMatchers("/api/v1/signup").permitAll().
         anyRequest().authenticated().
         and().
         anonymous().disable();
        http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
    }

내 인증 필터는

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = asHttp(request);
        HttpServletResponse httpResponse = asHttp(response);

        String username = httpRequest.getHeader("X-Auth-Username");
        String password = httpRequest.getHeader("X-Auth-Password");
        String token = httpRequest.getHeader("X-Auth-Token");

        String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);

        try {

            if (postToAuthenticate(httpRequest, resourcePath)) {            
                processUsernamePasswordAuthentication(httpResponse, username, password);
                return;
            }

            if(token != null){
                processTokenAuthentication(token);
            }
            chain.doFilter(request, response);
        } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
            SecurityContextHolder.clearContext();
            logger.error("Internal authentication service exception", internalAuthenticationServiceException);
            httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } catch (AuthenticationException authenticationException) {
            SecurityContextHolder.clearContext();
            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
        } finally {
        }
    }

     private HttpServletRequest asHttp(ServletRequest request) {
            return (HttpServletRequest) request;
        }

        private HttpServletResponse asHttp(ServletResponse response) {
            return (HttpServletResponse) response;
        }

        private boolean postToAuthenticate(HttpServletRequest httpRequest, String resourcePath) {
            return Constant.AUTHENTICATE_URL.equalsIgnoreCase(resourcePath) && httpRequest.getMethod().equals("POST");
        }

        private void processUsernamePasswordAuthentication(HttpServletResponse httpResponse,String username, String password) throws IOException {
            Authentication resultOfAuthentication = tryToAuthenticateWithUsernameAndPassword(username, password);
            SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
            httpResponse.setStatus(HttpServletResponse.SC_OK);
            httpResponse.addHeader("Content-Type", "application/json");
            httpResponse.addHeader("X-Auth-Token", resultOfAuthentication.getDetails().toString());
        }

        private Authentication tryToAuthenticateWithUsernameAndPassword(String username,String password) {
            UsernamePasswordAuthenticationToken requestAuthentication = new UsernamePasswordAuthenticationToken(username, password);
            return tryToAuthenticate(requestAuthentication);
        }

        private void processTokenAuthentication(String token) {
            Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
            SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
        }

        private Authentication tryToAuthenticateWithToken(String token) {
            PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
            return tryToAuthenticate(requestAuthentication);
        }

        private Authentication tryToAuthenticate(Authentication requestAuthentication) {
            Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
            if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
                throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
            }
            logger.debug("User successfully authenticated");
            return responseAuthentication;
        }

내 컨트롤러는

@RestController
public class UserController {

    @Autowired
    UserService userService;

    /**
     * to pass user info to service
     */
    @RequestMapping(value = "api/v1/signup",method = RequestMethod.POST)
    public String saveUser(@RequestBody User user) {
        userService.saveUser(user);
        return "User registerted successfully";
    }
}

나는 봄에 완전히 새롭다, 나에게 그것을하는 방법을 저에게 도와주세요?

해결법

  1. ==============================

    1.permitAll을 사용하면 모든 인증 된 사용자를 의미하지만 익명 액세스를 사용하지 않도록 설정하면 작동하지 않습니다.

    permitAll을 사용하면 모든 인증 된 사용자를 의미하지만 익명 액세스를 사용하지 않도록 설정하면 작동하지 않습니다.

    당신이 원하는 것은 WebSecurity 객체를 취하고 패턴을 무시하는 configure 메소드를 재정의하기 위해 특정 URL을 무시하는 것입니다.

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/api/v1/signup");
    }
    

    그리고 HttpSecurity 부분에서 해당 행을 제거하십시오. 이렇게하면 Spring Security는이 URL을 무시하고 필터를 적용하지 않을 것입니다.

  2. ==============================

    2.나는 더 좋은 방법이있다.

    나는 더 좋은 방법이있다.

    http
        .authorizeRequests()
        .antMatchers("/api/v1/signup/**").permitAll()
        .anyRequest().authenticated()
    
  3. ==============================

    3.

    <http pattern="/resources/**" security="none"/>
    

    또는 자바 구성 :

    web.ignoring().antMatchers("/resources/**");
    

    오래된 것 대신에 :

     <intercept-url pattern="/resources/**" filters="none"/>
    

    exp. 로그인 페이지의 보안을 비활성화하십시오.

      <intercept-url pattern="/login*" filters="none" />
    
  4. ==============================

    4.이것은 귀하의 질문에 대한 완전한 답변이 아니지만 csrf 보호를 비활성화하는 방법을 찾고 계시다면 다음과 같이하십시오 :

    이것은 귀하의 질문에 대한 완전한 답변이 아니지만 csrf 보호를 비활성화하는 방법을 찾고 계시다면 다음과 같이하십시오 :

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/web/admin/**").hasAnyRole(ADMIN.toString(), GUEST.toString())
                    .anyRequest().permitAll()
                    .and()
                    .formLogin().loginPage("/web/login").permitAll()
                    .and()
                    .csrf().ignoringAntMatchers("/contact-email")
                    .and()
                    .logout().logoutUrl("/web/logout").logoutSuccessUrl("/web/").permitAll();
        }
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("admin").password("admin").roles(ADMIN.toString())
                    .and()
                    .withUser("guest").password("guest").roles(GUEST.toString());
        }
    
    }
    

    전체 구성을 포함 시켰지만 핵심은 다음과 같습니다.

    .csrf().ignoringAntMatchers("/contact-email")
    
  5. from https://stackoverflow.com/questions/30366405/how-to-disable-spring-security-for-particular-url by cc-by-sa and MIT license