2015-10-11 5 views
7

मैं वसंत बूट डाटा बाकी भंडार का उपयोग कर मेरी User संस्थाओंस्प्रिंग बूट डाटा में इकाई सत्यापन के बाद @HandleBeforeCreate चल रहा है बाकी

@Entity 
public class User { 

    @Id 
    @GeneratedValue 
    private long id; 

    @NotEmpty 
    private String firstName; 

    @NotEmpty 
    private String lastName; 

    @NotEmpty 
    private String email; 

    @Size(min = 5, max = 20) 
    private String password; 

    // getters and setters 
} 

लागू करने के लिए उपयोग कर रहा हूँ:

public interface UserRepository extends CrudRepository<User, Long> {} 

मैं आपकी क्या अपेक्षाएं हैं

@Configuration 
public class CustomRestConfiguration extends SpringBootRepositoryRestMvcConfiguration { 

    @Autowired 
    private Validator validator; 

    @Override 
    protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { 
     validatingListener.addValidator("beforeCreate", validator); 
    } 

} 

और केवल: पहला POST एड उपयोगकर्ताओं को मान्य है बाद में डीबी में भंडारण से पहले उपयोगकर्ता का पासवर्ड हैश:

@Component 
@RepositoryEventHandler(User.class) 
public class UserRepositoryEventHandler { 

    private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 

    @HandleBeforeCreate 
    public void handleUserCreate(User user) { 
     user.setPassword(passwordEncoder.encode(user.getPassword())); 
    } 
} 

यह हालांकि पता चला है के रूप में, मान्यता पासवर्ड हैशिंग के बाद किया जाता है और एक परिणाम के रूप में यह विफल रहता है के कारण बहुत लंबा किया जा रहा पासवर्ड टुकड़ों में बांटा।

क्या स्प्रिंग को पहले सत्यापन करने के लिए निर्देश देने का कोई तरीका है और केवल तब पासवर्ड हैश? मुझे पता है कि मैं खुद को एक नियंत्रक लिख सकता हूं और सब कुछ ठीक तरीके से निर्दिष्ट कर सकता हूं, लेकिन मैं इसे अपने अंतिम उपाय के रूप में छोड़ दूंगा।

+1

क्या आप वसंत बूट/डेटा आरईएसटी का उपयोग कर रहे हैं? मैंने बस अपने ऐप पर इसका परीक्षण किया और जब मैंने रेपो हैंडलर और 'साइज वैलिडेटर फोरशेरस्यून्स' में ब्रेकपॉइंट लगाया, तो वैधकर्ता में से एक हैंडलर से पहले मारा जाता है, इसलिए मेरे लिए यह अपेक्षा के अनुसार काम करता है। मैं वसंत बूट 1.2.5 –

+0

@ बोहुस्लावबुर्गगार्ट का उपयोग कर रहा हूं मैं वसंत बूट '1.2.6.RELEASE' पर हूं और यह अन्य सभी निर्भरता संस्करणों का प्रबंधन करता है। मैं वास्तव में नहीं जानता कि सत्यापनकर्ता पर ब्रेकपॉइंट कैसे डाला जाए, क्योंकि मैं जेपीए द्वारा बनाई गई एक (मुझे लगता है) को स्वचालित करता है। यह दृश्यों के पीछे कहीं भी होता है। ऐसा करने की कोशिश करेंगे हालांकि – Wojtek

+0

@Wojtek, क्या कोई अन्य हुक है जिसका उपयोग मैं सफल बीन सत्यापन (इसे अस्तित्व में रखने से पहले) के बाद नियंत्रण प्राप्त कर सकता हूं? – masT

उत्तर

2

जैसा कि मैंने डीबगर में जांच में पता चला कि एक इनकमिंग इकाई निम्न क्रम में संसाधित किया जाता है: जब SpringValidatorAdapter::validate में JSON deserializing

  1. वसंत सेम सत्यापन करता है। यहां पासवर्ड सादा पाठ में है।
  2. @HandleBeforeCreate आह्वान किया गया है और पासवर्ड धोया गया है।
  3. जेपीए डीबी में इसे सहेजने से पहले इकाई सत्यापन करता है। यहां पासवर्ड पहले से ही धोया गया है और सत्यापन विफल रहता है। मेरे मामले में (जेपीए के हाइबरनेट कार्यान्वयन) सत्यापन BeanValidationEventListener::validate में किया गया था।

समाधान 1 (दोनों चरणों में पूर्ण मान्यता)

एक समाधान मैंने पाया बस @NotEmpty का उपयोग कर (ताकि दोनों सत्यापन चरणों पारित कर दिया है और अब भी भेजे JSON द्वारा password मैदान पर बाधा आराम करने के लिए था खालीपन/शून्यता के लिए जांच की गई थी) और @HandleBeforeCreate में कच्चे पासवर्ड का आकार सत्यापन (और यदि आवश्यक हो तो वहां से उचित अपवाद फेंक दें)।

इस समाधान के साथ समस्या यह है कि मुझे अपने अपवाद हैंडलर लिखने की आवश्यकता है। त्रुटि प्रतिक्रिया निकाय के संबंध में स्प्रिंग डेटा आरईएसटी द्वारा निर्धारित उच्च मानकों को बनाए रखने के लिए, मुझे इस एक साधारण मामले के लिए बहुत सारे कोड लिखना होगा। ऐसा करने का तरीका here वर्णित है।

समाधान 2 (जेपीए इकाई सत्यापन के बिना स्प्रिंग सेम मान्यता)

Bohuslav Burghardt द्वारा संकेत दिया है, यह जेपीए के द्वारा किया दूसरा सत्यापन चरण निष्क्रिय करने के लिए संभव है। इस तरह आप न्यूनतम और अधिकतम बाधाओं को रख सकते हैं और साथ ही साथ कोई अतिरिक्त कोड लिखने से बच सकते हैं। हमेशा की तरह यह सादगी और सुरक्षा के बीच एक व्यापार बंद है। जेपीए को अक्षम करने का तरीका here वर्णित है।

समाधान 3 (केवल पासवर्ड लंबाई बाधा मिनट संरक्षण)

एक अन्य समाधान, कम से कम मेरे मामले में वैध, अधिकतम पासवर्ड लंबाई असीम छोड़ने के लिए गया था। इस तरह के पहले सत्यापन चरण में पासवर्ड की जांच की गई थी कि यह बहुत छोटा नहीं था और दूसरे चरण में यह हर बार प्रभावी रूप से मान्य होता था (क्योंकि एन्क्रिप्टेड पासवर्ड पहले से ही काफी लंबा था)।

इस समाधान के लिए एकमात्र चेतावनी यह है कि @Size(min = 5) शून्यता की जांच नहीं कर रहा है इसलिए मुझे इस मामले को संभालने के लिए @NotNull जोड़ना पड़ा। सभी क्षेत्रों में सभी को एनोटेट किया गया है:

@NotNull 
@Size(min = 5) 
private String password; 
+1

दिलचस्प पढ़ना। मेरे लिए यह काम करने का कारण शायद इसलिए है क्योंकि मेरे पास application.properties ('spring.jpa.properties.javax.persistence.validation.mode = none') के माध्यम से हाइबरनेट सत्यापन अक्षम है। आप भी ऐसा कर सकते हैं, फिर केवल चरण 1 पर deserialization के दौरान सत्यापन किया जाएगा। –

+0

हां, मैंने इसके बारे में पढ़ा लेकिन मैं वास्तव में सभी जेपीए सत्यापन भलाई से इस्तीफा नहीं देना चाहता था :) इसे एक और संभावित समाधान के रूप में जोड़ देगा। बोहुस्लाव आपकी मदद के लिए धन्यवाद! – Wojtek

+1

रेगेक्स के साथ स्ट्रिंग को मान्य करने के बारे में कैसे? – Kenji

संबंधित मुद्दे