स्प्रिंग बूट और स्प्रिंग सिक्योरिटी के साथ REST API को कैसे सुरक्षित करें?


80

मुझे पता है कि REST API हासिल करना व्यापक रूप से विषय है, लेकिन मैं एक छोटा प्रोटोटाइप नहीं बना पा रहा हूं जो मेरे मानदंडों को पूरा करता हो (और मुझे यह पुष्टि करने की आवश्यकता है कि ये मानदंड यथार्थवादी हैं)। बहुत सारे विकल्प हैं कि संसाधनों को कैसे सुरक्षित किया जाए और स्प्रिंग सुरक्षा के साथ कैसे काम किया जाए, मुझे स्पष्ट करना होगा कि क्या मेरी ज़रूरतें यथार्थवादी हैं।

मेरी आवश्यकताएं

  • टोकन आधारित प्रमाणीकरणकर्ता - उपयोगकर्ता अपनी साख प्रदान करेंगे और अद्वितीय और समय सीमित टोकन प्राप्त करेंगे। मैं अपने स्वयं के कार्यान्वयन में टोकन निर्माण, वैधता की जांच, समाप्ति की व्यवस्था करना चाहता हूं।
  • कुछ REST संसाधन सार्वजनिक होंगे - सभी को प्रमाणित करने की आवश्यकता नहीं है,
  • कुछ संसाधन केवल व्यवस्थापक अधिकारों वाले उपयोगकर्ताओं के लिए सुलभ होंगे,
  • सभी उपयोगकर्ताओं के लिए प्राधिकरण के बाद अन्य संसाधन सुलभ होंगे।
  • मैं मूल प्रमाणीकरण का उपयोग नहीं करना चाहता
  • जावा कोड कॉन्फ़िगरेशन (XML नहीं)

वर्तमान स्थिति

मेरा REST API बहुत अच्छा काम करता है, लेकिन अब मुझे इसे सुरक्षित करने की आवश्यकता है। जब मैं एक हल ढूंढ रहा था तो मैंने एक javax.servlet.Filterफ़िल्टर बनाया :

  @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
        Account account = accountDao.find(accessToken);

        if (account == null) {    
            throw new UnauthorizedException();    
        }

        chain.doFilter(req, res);

    }

लेकिन यह समाधान javax.servlet.filtersमेरे लिए आवश्यक नहीं है क्योंकि @ControllerAdviceस्प्रिंग के साथ अपवाद से निपटने के साथ एक समस्या है servlet dispatcher

क्या चाहिए मुझे

मैं जानना चाहूंगा कि क्या ये मानदंड वास्तविक हैं और कोई मदद मिलती है, वसंत सुरक्षा के साथ REST API को कैसे शुरू किया जाए। मैंने कई ट्यूटोरियल पढ़े (जैसे स्प्रिंग डेटा रीस्ट + स्प्रिंग सिक्योरिटी ) लेकिन सभी बहुत ही बुनियादी विन्यास में काम करते हैं - अपने क्रेडेंशियल्स वाले उपयोगकर्ता कॉन्फ़िगरेशन में मेमोरी में संग्रहीत होते हैं और मुझे डीबीएमएस के साथ काम करने और स्वयं प्रमाणक बनाने की आवश्यकता होती है।

कृपया मुझे कुछ विचार दें कि कैसे शुरू करें।

जवाबों:


67

टोकन आधारित प्रमाणीकरण - उपयोगकर्ता इसकी विश्वसनीयता प्रदान करेंगे और अद्वितीय और समय सीमित पहुंच टोकन प्राप्त करेंगे। मैं अपने स्वयं के कार्यान्वयन में टोकन निर्माण, वैधता की जांच, समाप्ति की व्यवस्था करना चाहता हूं।

वास्तव में, टोकन के लिए फ़िल्टर का उपयोग करें प्रामाणिक - इस मामले में सबसे अच्छा तरीका है

आखिरकार, आप टोकन के गुणों को समाप्त करने के लिए प्रबंधन के लिए स्प्रिंग डेटा के माध्यम से सीआरयूडी बना सकते हैं, जैसे कि समाप्त हो जाना, आदि।

यहाँ मेरा टोकन फ़िल्टर है: http://pastebin.com/13WWpLq2

और टोकन सेवा कार्यान्वयन

http://pastebin.com/dUYM555E

कुछ REST संसाधन सार्वजनिक होंगे - सभी को प्रमाणित करने की आवश्यकता नहीं है

यह कोई समस्या नहीं है, आप अपने संसाधनों को इस तरह से स्प्रिंग सुरक्षा कॉन्फिग के माध्यम से प्रबंधित कर सकते हैं: .antMatchers("/rest/blabla/**").permitAll()

कुछ संसाधन केवल व्यवस्थापक अधिकारों वाले उपयोगकर्ताओं के लिए सुलभ होंगे,

@Securedकक्षा में एनोटेशन पर एक नज़र डालें । उदाहरण:

@Controller
@RequestMapping(value = "/adminservice")
@Secured("ROLE_ADMIN")
public class AdminServiceController {

अन्य संसाधन सभी उपयोगकर्ताओं के लिए प्राधिकरण के बाद सुलभ होंगे।

बैक टू स्प्रिंग सिक्योरिटी कॉन्फ़िगर, आप अपने यूआरएल को इस तरह कॉन्फ़िगर कर सकते हैं:

    http
            .authorizeRequests()
            .antMatchers("/openforall/**").permitAll()
            .antMatchers("/alsoopen/**").permitAll()
            .anyRequest().authenticated()

मैं मूल प्रमाणीकरण का उपयोग नहीं करना चाहता

हां, टोकन फ़िल्टर के माध्यम से, आपके उपयोगकर्ता प्रमाणित होंगे।

जावा कोड कॉन्फ़िगरेशन (XML नहीं)

उपरोक्त शब्दों पर वापस, देखें @EnableWebSecurity। आपकी कक्षा होगी:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

आपको कॉन्फ़िगर विधि को ओवरराइड करना होगा । नीचे कोड, उदाहरण के लिए, मैचर्स को कैसे कॉन्फ़िगर करें। यह दूसरे प्रोजेक्ट से है।

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/assets/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .loginPage("/login")
                .defaultSuccessUrl("/", true)
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
                .logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .and()
                .csrf();
}

क्या आप कृपया मेरे प्रश्न में मेरी मदद कर सकते हैं? stackoverflow.com/questions/46065063/…
फेलिप ए।

2
कोई भी उदाहरण परियोजना जिसमें सभी आवश्यकताएं शामिल हैं?
एलिकएल्ज़िन-किलाका

@ ऑलेक्ज़ेंडर: यह एक लंबा शॉट है, लेकिन क्या आप मुझे बता सकते हैं कि आपने RESTAuthenticationTokenProcessingFilter क्लास की अपडेटLastLogin (...) विधि में एक धागा क्यों शुरू किया है?
Z3d4s 20

1
@ z3d4s, वास्तव में यह एक पुराना उदाहरण है (4 वर्ष), अब मैं ऑफ़सेटडाईटटाइम, एक अन्य दृष्टिकोण आदि का उपयोग करने का सुझाव दूंगा :) नया धागा मैंने उपयोगकर्ता अनुरोधों के लिए प्रसंस्करण समय को कम करने के लिए उपयोग करने का प्रस्ताव दिया, क्योंकि इसे बचाने में अतिरिक्त समय लग सकता है डेटाबेस में।
ऑलेक्ज़ेंडर लूशकीन

आह, मैं देखता हूँ, एक प्रतिभाशाली समाधान है! धन्यवाद!
Z3d4s

4

REST URL को प्रमाणीकरण और प्रमाणीकरण प्रदान करने के लिए स्प्रिंग सुरक्षा भी बहुत उपयोगी है। हमें कोई कस्टम कार्यान्वयन निर्दिष्ट करने की आवश्यकता नहीं है।

सबसे पहले, आपको नीचे दिए गए अपने सुरक्षा कॉन्फ़िगरेशन में restAuthenticationEntryPoint में प्रविष्टि-बिंदु-निर्दिष्ट करने की आवश्यकता है।

 <security:http pattern="/api/**" entry-point-ref="restAuthenticationEntryPoint" use-expressions="true" auto-config="true" create-session="stateless" >

    <security:intercept-url pattern="/api/userList" access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/api/managerList" access="hasRole('ROLE_ADMIN')"/>
    <security:custom-filter ref="preAuthFilter" position="PRE_AUTH_FILTER"/>
</security:http>

RestAuthenticationEntryPoint के लिए कार्यान्वयन नीचे के रूप में हो सकता है।

 @Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

   public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException ) throws IOException {
      response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
   }
}

इसके बाद आपको RequestHeaderAuthenticationFilter को निर्दिष्ट करने की आवश्यकता है। इसमें RequestHeader कुंजी है। यह मूल रूप से उपयोगकर्ता के प्रमाणीकरण की पहचान करने के लिए उपयोग किया जाता है। आम तौर पर RequestHeader REST कॉल करते समय इस जानकारी को वहन करता है। उदाहरण के लिए नीचे दिए गए कोड पर विचार करें

   <bean id="preAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="Authorization"/>
    <property name="authenticationManager" ref="authenticationManager" />
  </bean>

यहाँ,

<property name="principalRequestHeader" value="Authorization"/>

"प्राधिकरण" कुंजी है आने वाले अनुरोध को प्रस्तुत किया। यह आवश्यक उपयोगकर्ता की प्रमाणीकरण जानकारी रखता है। साथ ही आपको हमारी आवश्यकता को पूरा करने के लिए PreAuthenticatedAuthenticationProvider को कॉन्फ़िगर करना होगा।

   <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
  <bean id="userDetailsServiceWrapper"
      class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
    <property name="userDetailsService" ref="authenticationService"/>
  </bean>
</property>
</bean>

यह कोड किसी भी कस्टम कार्यान्वयन के बिना प्रमाणीकरण और प्राधिकरण के माध्यम से अन्य url को सुरक्षित करने के लिए काम करेगा।

पूर्ण कोड के लिए कृपया नीचे दिया गया लिंक खोजें:

https://github.com/srinivas1918/spring-rest-security


0

मैंने इस लंबे समय को भी खोजा। मैं एक समान परियोजना पर काम कर रहा हूं। मैंने पाया कि स्प्रिंग में रेडिस के माध्यम से सत्र को लागू करने के लिए एक मॉड्यूल है। यह आसान और उपयोगी लगता है। मैं अपने प्रोजेक्ट से भी जुड़ूंगा। मददगार हो सकते हैं:

http://docs.spring.io/spring-session/docs/1.2.1.BUILD-SNAPSHOT/reference/html5/guides/rest.html


-1

REST API को मान्य करने के लिए 2 तरीके हैं

1 - मूलभूत उपयोगकर्ता नाम और कूटशब्द का उपयोग करके मूल प्रमाणीकरण। application.properties फ़ाइल

मूल प्रमाणीकरण

2 - वास्तविक उपयोगकर्ता नाम और पासवर्ड के साथ डेटाबेस (userDetailsService) का उपयोग करके प्रमाणित करें

उन्नत प्रमाणीकरण


वीडियो उपयोगी है। ReST API के लिए समान उन्नत प्रमाणीकरण कैसे करें। यहाँ केवल वेब के बारे में वर्णन किया गया है। क्या REST API में उन्नत प्रमाणीकरण के लिए कोई वीडियो ट्यूटोरियल है।
जैकब

यदि आपने दूसरा वीडियो (उन्नत प्रमाणीकरण) देखा, तो उसमें मैं उसी तरह REST क्लाइंट (REST API के लिए) का उपयोग करके प्रमाणीकरण कर रहा हूं।
जीत सिंह परमार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.