Belirli url için yay güvenliği nasıl devre dışı bırakılır


88

Vatansız yay güvenliği kullanıyorum, ancak kaydolma durumunda yay güvenliğini devre dışı bırakmak istiyorum. Kullanarak devre dışı bıraktım

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

ama çalışmıyor, aşağıda hata alıyorum:

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

Sanırım bu, yaylı güvenlik filtrelerinin çalıştığı anlamına geliyor

URL'min sırası her zaman "/ api / v1" olacak

Bahar yapılandırmam

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

Kimlik doğrulama filtrem

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

Denetleyicim

@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";
    }
}

İlkbaharda tamamen yeniyim, lütfen nasıl yapacağıma yardım et?


Yanıtlar:


161

Kullanırken permitAll, kimliği doğrulanmış her kullanıcı anlamına gelir, ancak anonim erişimi devre dışı bıraktınız, böylece işe yaramaz.

İstediğiniz şey configure, WebSecuritynesneyi ve ignorekalıbı alan yöntemi geçersiz kılmak için belirli URL'leri yok saymaktır.

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

Ve o çizgiyi HttpSecurityparçadan çıkarın . Bu, Spring Security'ye bu URL'yi göz ardı etmesini ve bunlara herhangi bir filtre uygulamamasını söyleyecektir.


4
bu hangi dosyaya yazılır?
Jacob Zimmerman

3
@JacobZimmerman spring.io/blog/2013/07/03/… web güvenlik sınıfı yapılandırıcısı
Askar Ibragimov

1
Sadece uzatmak zorunda eklemek istiyorum WebSecurityConfigurerAdapterve overridebu methodonun içinde.
muasif80

20

Daha iyi bir yolum var:

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

3
Bu pasajın nerede çağrılması gerekiyor?
Viacheslav Shalamov

Senin içinde @ViacheslavShalamov WebSecurityConfig extends WebSecurityConfigurerAdapterbireyin configure(HttpSecurity http)yöntemle. Bkz. Baeldung.com/java-config-spring-security
jAC

1
bu internette en yaygın olanıdır, aslında yanlış bir uygulamadır. Her şeye izin verirseniz, hala doğrulanması gerektiğini kastediyorsunuz ama sonunda buna izin veriyorsunuz. öyleyse bir kayıt erişimi için neden kimlik doğrulaması yapmalıyız (yani kimlik doğrulama filtreleri hala tetiklenecek)?
Chao

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

Veya Java yapılandırmasıyla:

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

Eskinin yerine:

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

exp için. bir oturum açma sayfası için güvenliği devre dışı bırakın:

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

9

Bu, sorunuzun tam cevabı olmayabilir, ancak csrf korumasını devre dışı bırakmanın bir yolunu arıyorsanız şunları yapabilirsiniz:

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

}

Tam yapılandırmayı dahil ettim ancak ana satır şudur:

.csrf().ignoringAntMatchers("/contact-email")

2

@ M.Deinum cevabı zaten yazmış.

API ile denedim /api/v1/signup. filtre / özel filtreyi atlayacak, ancak tarayıcı tarafından çağrılan ek bir istek /favicon.ico, bu yüzden bunu web.ignoring () 'e de ekliyorum ve benim için çalışıyor.

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

Belki yukarıdaki soru için bu gerekli değildir.


2

Birden çok API uç noktasını yok saymak istiyorsanız, aşağıdaki gibi kullanabilirsiniz:

 @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable().authorizeRequests() 
            .antMatchers("/api/v1/**").authenticated()
            .antMatchers("api/v1/authenticate**").permitAll()
            .antMatchers("**").permitAll()
            .and().exceptionHandling().and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

0

Aynı problemle karşılaştım, işte çözüm: ( Açıklandı )

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers(HttpMethod.POST,"/form").hasRole("ADMIN")  // Specific api method request based on role.
            .antMatchers("/home","/basic").permitAll()  // permited urls to guest users(without login).
            .anyRequest().authenticated()
            .and()
        .formLogin()       // not specified form page to use default login page of spring security.
            .permitAll()
             .and()
        .logout().deleteCookies("JSESSIONID")  // delete memory of browser after logout.

        .and()
        .rememberMe().key("uniqueAndSecret"); // remember me check box enabled.

    http.csrf().disable();  **// ADD THIS CODE TO DISABLE CSRF IN PROJECT.**
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.