MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

स्प्रिंग सुरक्षा और MongoDB के साथ प्रमाणीकरण

सच करना बहुत कठिन है, चल रहे लेख में रीयल-टाइम दृश्यता प्रवाह।

प्रक्रिया के कुछ हिस्सों को हमसे पूरी तरह छुपाया जा सकता है; यदि पूर्ण प्राधिकरण प्रक्रिया के लिए दूरस्थ OAuth उत्पादन सर्वर से पुनर्निर्देशन की आवश्यकता होती है, तो प्रत्येक डिबगिंग प्रयास को उत्पादन सर्वर के माध्यम से जाना चाहिए।

इसे स्थानीय रूप से डीबग करना व्यावहारिक रूप से असंभव है। सटीक स्थिति को पुन:पेश करने का कोई तरीका नहीं है और वास्तव में हुड के नीचे क्या हो रहा है इसका निरीक्षण करने का कोई तरीका नहीं है। आदर्श नहीं है।

इस प्रकार की चुनौतियों को जानते हुए, हमने लाइटरन - एक रीयल-टाइम प्रोडक्शन डिबगिंग टूल बनाया है - ताकि आप कोड-स्तरीय जानकारी के साथ जटिल प्रवाह को समझ सकें। लॉग जोड़ें, स्नैपशॉट लें (वर्चुअल ब्रेकप्वाइंट), और इंस्ट्रूमेंट मेट्रिक्स बिना रिमोट डीबगर के, बिना रनिंग सर्विस को रोके, और, सबसे महत्वपूर्ण - रियल-टाइम में और बिना साइड इफेक्ट के .

इस 5 मिनट के ट्यूटोरियल के साथ और जानें लाइटरून का उपयोग करके इस प्रकार के परिदृश्यों को डीबग करने पर ध्यान केंद्रित किया गया:

>> लाइटरून का उपयोग करके प्रमाणीकरण और प्राधिकरण को डिबग करना

1. अवलोकन

स्प्रिंग सिक्योरिटी विभिन्न प्रमाणीकरण प्रणाली प्रदान करती है, जैसे डेटाबेस और UserDetailService . के माध्यम से .

एक जेपीए दृढ़ता परत का उपयोग करने के बजाय, हम उदाहरण के लिए, एक मोंगोडीबी भंडार का भी उपयोग करना चाह सकते हैं। इस ट्यूटोरियल में, हम देखेंगे कि स्प्रिंग सिक्योरिटी और MongoDB का उपयोग करके उपयोगकर्ता को कैसे प्रमाणित किया जाए।

2. MongoDB के साथ स्प्रिंग सुरक्षा प्रमाणीकरण

JPA रिपॉजिटरी के उपयोग के समान, हम MongoDB रिपॉजिटरी का उपयोग कर सकते हैं . हालांकि, इसका उपयोग करने के लिए हमें एक अलग कॉन्फ़िगरेशन सेट करने की आवश्यकता है।

2.1. मावेन निर्भरताएं

इस ट्यूटोरियल के लिए, हम एंबेडेड MongoDB का उपयोग करने जा रहे हैं . हालांकि, एक MongoDB उदाहरण और टेस्टकंटेनर उत्पादन वातावरण के लिए वैध विकल्प हो सकते हैं। सबसे पहले, आइए स्प्रिंग-बूट-स्टार्टर-डेटा-मोंगोडब जोड़ें और de.flapdoodle.embed.mongo निर्भरताएँ:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <version>3.3.1</version>
</dependency>

2.2. कॉन्फ़िगरेशन

निर्भरता सेट करने के बाद, हम अपना कॉन्फ़िगरेशन बना सकते हैं:

@Configuration
public class MongoConfig {

    private static final String CONNECTION_STRING = "mongodb://%s:%d";
    private static final String HOST = "localhost";

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {

        int randomPort = SocketUtils.findAvailableTcpPort();

        ImmutableMongodConfig mongoDbConfig = MongodConfig.builder()
          .version(Version.Main.PRODUCTION)
          .net(new Net(HOST, randomPort, Network.localhostIsIPv6()))
          .build();

        MongodStarter starter = MongodStarter.getDefaultInstance();
        MongodExecutable mongodExecutable = starter.prepare(mongoDbConfig);
        mongodExecutable.start();
        return new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, HOST, randomPort)), "mongo_auth");
    }
}

हमें अपने प्रमाणीकरण प्रबंधक . को भी कॉन्फ़िगर करने की आवश्यकता है उदाहरण के लिए, एक HTTP मूल प्रमाणीकरण के साथ:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // ...
    public SecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(@Autowired AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
          .disable()
          .authorizeRequests()
          .and()
          .httpBasic()
          .and()
          .authorizeRequests()
          .anyRequest()
          .permitAll()
          .and()
          .sessionManagement()
          .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

2.3. उपयोगकर्ता डोमेन और रिपोजिटरी

सबसे पहले, आइए हमारे प्रमाणीकरण के लिए भूमिकाओं के साथ एक साधारण उपयोगकर्ता को परिभाषित करें। हम इसे उपयोगकर्ता विवरण लागू करेंगे प्रिंसिपल . के सामान्य तरीकों का पुन:उपयोग करने के लिए इंटरफ़ेस वस्तु:

@Document
public class User implements UserDetails {
    private @MongoId ObjectId id;
    private String username;
    private String password;
    private Set<UserRole> userRoles;
    // getters and setters
}

अब जब हमारे पास हमारा उपयोगकर्ता है, तो आइए एक साधारण भंडार को परिभाषित करें:

public interface UserRepository extends MongoRepository<User, String> {

    @Query("{username:'?0'}")
    User findUserByUsername(String username);
}

2.4. प्रमाणीकरण सेवा

आखिरकार, आइए हमारी UserDetailService को लागू करें किसी उपयोगकर्ता को पुनः प्राप्त करने और यह जांचने के लिए कि क्या यह प्रमाणित है :

@Service
public class MongoAuthUserDetailService implements UserDetailsService {
    // ...
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        com.baeldung.mongoauth.domain.User user = userRepository.findUserByUsername(userName);

        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();

        user.getAuthorities()
          .forEach(role -> {
              grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole()
                 .getName()));
          });

        return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
    }

}

2.5. परीक्षण प्रमाणीकरण

हमारे आवेदन का परीक्षण करने के लिए, आइए एक साधारण नियंत्रक को परिभाषित करें। एक उदाहरण के रूप में, हमने विशिष्ट समापन बिंदुओं के लिए प्रमाणीकरण और प्राधिकरण का परीक्षण करने के लिए दो अलग-अलग भूमिकाएँ परिभाषित की हैं:

@RestController
public class ResourceController {

    @RolesAllowed("ROLE_ADMIN")
    @GetMapping("/admin")
    public String admin() {
        return "Hello Admin!";
    }

    @RolesAllowed({ "ROLE_ADMIN", "ROLE_USER" })
    @GetMapping("/user")
    public String user() {
        return "Hello User!";
    }

}

यह जाँचने के लिए कि हमारा प्रमाणीकरण काम करता है या नहीं, इसे स्प्रिंग बूट टेस्ट में पूरा करते हैं। जैसा कि हम देख सकते हैं, हम किसी ऐसे व्यक्ति के लिए 401 कोड की अपेक्षा कर रहे हैं जो अमान्य क्रेडेंशियल प्रदान करता है या जो हमारे सिस्टम में मौजूद नहीं है :

class MongoAuthApplicationTest {

    // set up

    @Test
    void givenUserCredentials_whenInvokeUserAuthorizedEndPoint_thenReturn200() throws Exception {
        mvc.perform(get("/user").with(httpBasic(USER_NAME, PASSWORD)))
          .andExpect(status().isOk());
    }

    @Test
    void givenUserNotExists_whenInvokeEndPoint_thenReturn401() throws Exception {
        mvc.perform(get("/user").with(httpBasic("not_existing_user", "password")))
          .andExpect(status().isUnauthorized());
    }

    @Test
    void givenUserExistsAndWrongPassword_whenInvokeEndPoint_thenReturn401() throws Exception {
        mvc.perform(get("/user").with(httpBasic(USER_NAME, "wrong_password")))
          .andExpect(status().isUnauthorized());
    }

    @Test
    void givenUserCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn403() throws Exception {
        mvc.perform(get("/admin").with(httpBasic(USER_NAME, PASSWORD)))
          .andExpect(status().isForbidden());
    }

    @Test
    void givenAdminCredentials_whenInvokeAdminAuthorizedEndPoint_thenReturn200() throws Exception {
        mvc.perform(get("/admin").with(httpBasic(ADMIN_NAME, PASSWORD)))
          .andExpect(status().isOk());

        mvc.perform(get("/user").with(httpBasic(ADMIN_NAME, PASSWORD)))
          .andExpect(status().isOk());
    }
}

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB:सरणी तत्व की संपत्ति पर अद्वितीय अनुक्रमणिका

  2. एमजीओ गो सर्वर में बहुत अधिक खुली फाइलें

  3. MongoDB सुरक्षा के लिए सर्वोत्तम अभ्यास

  4. विभिन्न प्रकारों पर MongoDB सूचकांक

  5. MongoDB $nin क्वेरी ऑपरेटर