विशेष रूप से यूआरएल के लिए वसंत सुरक्षा को अक्षम कैसे करें


85

मैं स्टेटलेस स्प्रिंग सिक्योरिटी का इस्तेमाल कर रहा हूं, लेकिन साइनअप के मामले में मैं स्प्रिंग सिक्योरिटी को डिसेबल करना चाहता हूं। मैं यूज कर रहा हूं

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

मैं वसंत के लिए पूरी तरह से नया हूं, कृपया मेरी मदद करें कि यह कैसे करना है?


एक नजर डालते हैं: stackoverflow.com/questions/4487249/…
Krzysztof Cichocki

जवाबों:


156

permitAllइसका उपयोग करते समय प्रत्येक प्रमाणित उपयोगकर्ता का अर्थ है, हालांकि आपने अनाम उपयोग को अक्षम कर दिया है ताकि काम न हो।

आप जो चाहते हैं, इसके लिए कुछ URLs को अनदेखा करना है configureजो WebSecurityऑब्जेक्ट और ignoreपैटर्न को लेने वाली विधि को ओवरराइड करता है ।

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

और उस लाइन को HttpSecurityपार्ट से हटा दें । यह स्प्रिंग सिक्योरिटी को इस URL को नजरअंदाज करने के लिए बताएगा और उन पर कोई फ़िल्टर लागू नहीं करेगा।


4
यह किस फ़ाइल में लिखा गया है?
जैकब ज़िमरमैन

3
@JacobZimmerman spring.io/blog/2013/07/03/... वेब सुरक्षा वर्ग के लिए configurer
Askar इब्रागिमोव

1
बस जोड़ने के लिए विस्तार करने के लिए है चाहते हैं WebSecurityConfigurerAdapterऔर overrideइस methodउस में।
muasif80

19

मेरे पास एक बेहतर तरीका है:

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

3
इस स्निपेट को कहाँ कहा जाता है?
वायाचेस्लाव शाल्मोव

@ViacheslavShalamov अपने में WebSecurityConfig extends WebSecurityConfigurerAdapterकी configure(HttpSecurity http)विधि। Baeldung.com/java-config-spring-security
jAC

1
यह इंटरनेट में सबसे आम है, वास्तव में यह गलत अभ्यास है। यदि आप सभी को अनुमति देते हैं, तो इसका मतलब है कि आपको अभी भी प्रमाणित करने की आवश्यकता है लेकिन आप अंततः इसे अनुमति देते हैं। इसलिए हमें साइन अप एक्सेस के लिए प्रमाणीकरण (मेरा मतलब है कि प्रमाणीकरण फ़िल्टर अभी भी चालू हो जाएगा) क्यों करना चाहिए?
चाओ

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

या जावा कॉन्फ़िगरेशन के साथ:

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

पुराने के बजाय:

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

विस्तार के लिए। लॉगिन पृष्ठ के लिए सुरक्षा अक्षम करें:

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

9

यह आपके प्रश्न का पूर्ण उत्तर नहीं हो सकता है, हालांकि यदि आप सीएसआरएफ सुरक्षा को अक्षम करने का तरीका खोज रहे हैं तो आप कर सकते हैं:

@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")

2

जैसा कि @ M.Deinum ने पहले ही जवाब लिख दिया था।

मैंने आपी के साथ कोशिश की /api/v1/signup। यह फ़िल्टर / कस्टम फ़िल्टर को बायपास कर देगा, लेकिन इसके लिए ब्राउज़र द्वारा /favicon.icoमंगवाया गया एक अतिरिक्त अनुरोध , इसलिए, मैं इसे web.ignoring () में भी जोड़ता हूं और यह मेरे लिए काम करता है।

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

हो सकता है कि उपरोक्त प्रश्न के लिए यह आवश्यक न हो।


2

यदि आप कई एपीआई एंडपॉइंट्स को अनदेखा करना चाहते हैं, तो आप निम्नानुसार उपयोग कर सकते हैं:

 @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

मैं यहाँ एक ही समस्या का समाधान है: ( समझाया )

@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.**
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.