उस समय के लिए निम्नलिखित समाधान के साथ आया है। चूंकि मेरी परियोजना अपेक्षाकृत सरल है क्योंकि यह एक और जटिल परियोजना के लिए काम नहीं कर सकती है।
- एक उपयोगकर्ता या तो सभी या पढ़ सकते हैं एक निश्चित वर्ग
की संस्थाओं इसलिए किसी भी प्रश्न विधि @PreAuthorize
युक्त hasRole
साथ टिप्पणी की जा सकती में से कोई भी।
यह अपवाद मेरे प्रोजेक्ट में Container
इकाई है। इसमें Compound
का कोई उप-वर्ग हो सकता है और उपयोगकर्ता को उन सभी को देखने का विशेषाधिकार नहीं हो सकता है। वे फिल्टर होना चाहिए।
इसके लिए मैंने User
और Role
इकाई बनाई। Compound
में Role
पर एक OneToOne संबंध है और वह भूमिका Compound
के लिए "read_role" है। User
और Role
में बहुत से रिश्ते हैं।
@Entity
public abstract class Compound {
//...
@OneToOne
private Role readRole;
//...
}
मेरे सभी खजाने QueryDSLPredicateExecutor
को लागू करने और है कि यहाँ बहुत हाथ हो जाता है। भंडार में कस्टम खोज-तरीकों को बनाने के बजाय हम उन्हें केवल सेवा परत में बनाते हैं और repositry.findAll(predicate)
और repository.findOne(predicate)
का उपयोग करते हैं। भविष्यवाणी वास्तविक उपयोगकर्ता इनपुट + "सुरक्षा फ़िल्टर" रखती है।
@PreAuthorize("hasRole('read_Container'")
public T getById(Long id) {
Predicate predicate = QCompoundContainer.compoundContainer.id.eq(id);
predicate = addSecurityFilter(predicate);
T container = getRepository().findOne(predicate);
return container;
}
private Predicate addSecurityFilter(Predicate predicate){
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
predicate = QCompoundContainer.compoundContainer.compound.readRole
.users.any().username.eq(userName).and(predicate);
return predicate;
}
नोट: QCompoundContainer
"मेटा मॉडल" QueryDSL द्वारा उत्पन्न वर्ग है।
पिछले आप शायद Container
से User
को QueryDSL पथ प्रारंभ करने की आवश्यकता:
@Entity
public abstract class CompoundContainer<T extends Compound>
//...
@QueryInit("readRole.users") // INITIALIZE QUERY PATH
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL,
targetEntity=Compound.class)
private T compound;
//...
}
इस अंतिम चरण के एक NullPointerException
को जन्म दे सकता हटा रहा है।
इसके अलावा संकेत: CompoundService
स्वचालित रूप से बचाने पर भूमिका सेट:
if (compound.getReadRole() == null) {
Role role = roleRepository.findByRoleName("read_" + getCompoundClassSimpleName());
if (role == null) {
role = new Role("read_" + getCompoundClassSimpleName());
role = roleRepository.save(role);
}
compound.setReadRole(role);
}
compound = getRepository().save(compound)
यह काम करता है। नकारात्मक थोड़ा सा स्पष्ट है। वही Role
उसी Compound
वर्ग कार्यान्वयन के प्रत्येक एकल उदाहरण से जुड़ा हुआ है।
प्रश्न के लिए एक को देखने [उपयोगकर्ता स्कीमा] (http://static.springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#d0e8380]) अनुभाग –
मैं बहुत मतलब कि मैं मौजूदा उपयोगकर्ताओं की भूमिकाओं को ध्यान में रखकर प्रश्नों को समायोजित कर सकता हूं, उदाहरण के लिए। किसी दिए गए इकाई से भूमिका और उपयोगकर्ता से भूमिका तक संबंध होना चाहिए। –
फिर एसीएल http://static.springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#domain-acls और उपयुक्त डीबी स्कीमा http: // static में एक नज़र डालें। springsource.org/spring-security/site/docs/3.2.x/reference/springsecurity-single.html#dbschema-acl –