स्प्रिंग सिक्योरिटी में रोल और ग्रांटेडऑथोरिटी के बीच अंतर


227

स्प्रिंग सुरक्षा में अवधारणाएं और कार्यान्वयन हैं, जैसे किसी एक्सेस को अधिकृत / नियंत्रित GrantedAuthorityकरने के लिए एक प्राधिकरण प्राप्त करने के लिए इंटरफ़ेस ।

मैं चाहता हूँ कि अनुमति के लिए संचालन, जैसे createSubUsers , या deleteAccounts , जो मैं एक व्यवस्थापक (भूमिका के साथ ROLE_ADMIN) को अनुमति दूंगा

मैं ऑनलाइन देखे जाने वाले ट्यूटोरियल / डेमो के रूप में भ्रमित हो रहा हूं। मैं जो कुछ भी पढ़ता हूं उसे जोड़ने की कोशिश करता हूं, लेकिन मुझे लगता है कि हम दोनों का परस्पर व्यवहार करते हैं।

मैं hasRoleएक GrantedAuthorityतार की खपत देख रहा हूँ ? मैं निश्चित रूप से इसे समझने में गलत कर रहा हूं। वसंत सुरक्षा में ये वैचारिक क्या हैं?

मैं उस भूमिका के लिए अधिकारियों से अलग किसी उपयोगकर्ता की भूमिका को कैसे संग्रहीत करूं?

मैं उस org.springframework.security.core.userdetails.UserDetailsइंटरफ़ेस को भी देख रहा हूं , जो प्रमाणीकरण-प्रदाता संदर्भित DAO में उपयोग किया जाता है, जो खपत करता है User(नोट अंतिम दी गई योग्यता):

public User(String username, 
            String password, 
            boolean enabled, 
            boolean accountNonExpired,
            boolean credentialsNonExpired, 
            boolean accountNonLocked, 
            Collection<? extends GrantedAuthority> authorities)

या अन्य दो को अलग करने का कोई अन्य तरीका है? या यह समर्थित नहीं है और हमें अपना बनाना है?

जवाबों:


365

एक GrantedAuthority "अनुमति" या एक "अधिकार" होने के रूप में सोचो। उन "अनुमतियों" को (सामान्य रूप से) स्ट्रिंग्स ( getAuthority()विधि के साथ) के रूप में व्यक्त किया जाता है । वे तार आपको अनुमतियों की पहचान करने और अपने मतदाताओं को यह तय करने देते हैं कि क्या वे किसी चीज़ तक पहुंच प्रदान करते हैं

आप उपयोगकर्ताओं को सुरक्षा संदर्भ में डालकर विभिन्न GrantedAuthority (अनुमतियाँ) प्रदान कर सकते हैं। आप सामान्य रूप से अपने खुद के UserDetailsService को लागू करके करते हैं, जो आवश्यक GrantedAuthorities को लौटाता है एक UserDetails कार्यान्वयन देता है।

भूमिकाएं (जैसा कि वे कई उदाहरणों में उपयोग की जाती हैं) एक नामकरण सम्मेलन के साथ सिर्फ "अनुमति" हैं जो कहती हैं कि एक भूमिका एक GrantedAuthority है जो उपसर्ग के साथ शुरू होती है ROLE_। ज्यादा कुछ नहीं है। एक भूमिका सिर्फ एक GrantedAuthority है - एक "अनुमति" - एक "सही"। आप वसंत सुरक्षा में बहुत सारे स्थान देखते हैं, जहां इसके ROLE_उपसर्ग के साथ भूमिका विशेष रूप से भूमिका में निभाई जाती है जैसे कि रोलवॉटर में, जहां ROLE_उपसर्ग का उपयोग डिफ़ॉल्ट के रूप में किया जाता है। यह आपको ROLE_उपसर्गों से भूमिका नाम प्रदान करने की अनुमति देता है । वसंत सुरक्षा 4 से पहले, "भूमिकाओं" की इस विशेष हैंडलिंग का लगातार पालन नहीं किया गया है और अधिकारियों और भूमिकाओं को अक्सर एक ही माना जाता है (जैसा कि आप चाहें)hasAuthority()hasRole())। स्प्रिंग सिक्योरिटी 4 के साथ, भूमिकाओं का उपचार अधिक सुसंगत और कोड है जो "भूमिकाओं" (जैसे RoleVoter, hasRoleअभिव्यक्ति आदि) से संबंधित है, हमेशा ROLE_आपके लिए उपसर्ग जोड़ता है । तो hasAuthority('ROLE_ADMIN')इसका मतलब वही है hasRole('ADMIN')क्योंकि ROLE_उपसर्ग अपने आप जुड़ जाता है। भविष्य की जानकारी के लिए वसंत सुरक्षा 3 से 4 माइग्रेशन गाइड देखें।

लेकिन फिर भी: एक भूमिका एक विशेष ROLE_उपसर्ग के साथ एक प्राधिकरण है । तो वसंत सुरक्षा में 3 के @PreAuthorize("hasRole('ROLE_XYZ')")रूप में ही है @PreAuthorize("hasAuthority('ROLE_XYZ')")और वसंत सुरक्षा में 4 के @PreAuthorize("hasRole('XYZ')")रूप में ही है @PreAuthorize("hasAuthority('ROLE_XYZ')")

आपके उपयोग के मामले के बारे में:

उपयोगकर्ताओं के पास भूमिकाएं हैं और भूमिकाएं कुछ संचालन कर सकती हैं।

आप GrantedAuthoritiesउन भूमिकाओं के लिए समाप्त हो सकते हैं, जो उपयोगकर्ता किसी भूमिका से संबंधित हैं और भूमिकाएं निभा सकती हैं। GrantedAuthoritiesभूमिकाओं के लिए उपसर्ग ROLE_और संचालन उपसर्ग OP_। एक उदाहरण आपरेशन अधिकारियों हो सकता है के लिए OP_DELETE_ACCOUNT, OP_CREATE_USER, OP_RUN_BATCH_JOBआदि भूमिकाओं हो सकता है ROLE_ADMIN, ROLE_USER, ROLE_OWNERआदि

आप अपनी संस्थाओं GrantedAuthorityको इस तरह लागू कर सकते हैं (छद्म-कोड) उदाहरण:

@Entity
class Role implements GrantedAuthority {
    @Id
    private String id;

    @ManyToMany
    private final List<Operation> allowedOperations = new ArrayList<>();

    @Override
    public String getAuthority() {
        return id;
    }

    public Collection<GrantedAuthority> getAllowedOperations() {
        return allowedOperations;
    }
}

@Entity
class User {
    @Id
    private String id;

    @ManyToMany
    private final List<Role> roles = new ArrayList<>();

    public Collection<Role> getRoles() {
        return roles;
    }
}

@Entity
class Operation implements GrantedAuthority {
    @Id
    private String id;

    @Override
    public String getAuthority() {
        return id;
    }
}

आपके डेटाबेस में आपके द्वारा बनाई गई भूमिकाओं और संचालन की आईडी, GrantedAuthority प्रतिनिधित्व, उदाहरण के लिए ROLE_ADMIN, OP_DELETE_ACCOUNTआदि होगी। जब कोई उपयोगकर्ता प्रमाणित होता है, तो सुनिश्चित करें कि उसके सभी भूमिकाओं के सभी GrantedAuthorities और संबंधित संचालन UserDetails.getAuthorities () से वापस कर दिए जाते हैं। तरीका।

उदाहरण: आईडी के साथ व्यवस्थापक भूमिका ROLE_ADMINकार्य किया है OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOBयह करने के लिए सौंपा। आईडी के साथ उपयोगकर्ता की भूमिका ROLE_USERका संचालन होता है OP_READ_ACCOUNT

जिसके परिणामस्वरूप सुरक्षा के संदर्भ में एक व्यवस्थापक लॉग GrantedAuthorities होगा: ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT,OP_RUN_BATCH_JOB

एक उपयोगकर्ता यह लॉग करता है, यह करना होगा: ROLE_USER,OP_READ_ACCOUNT

UserDetailsService उन भूमिकाओं के सभी भूमिकाओं और सभी कार्यों को एकत्र करने और उन्हें लौटाए गए UserDetails उदाहरण में विधि getAuthorities () द्वारा उपलब्ध कराने का ध्यान रखेगा।


2
धन्यवाद! मैं हर जगह खोज रहा हूँ कि क्यों "hasRole ('rolename')" वसंत 4 में काम नहीं कर रहा था -> उनके प्रलेखन के माध्यम से स्किम करने के लिए बिल्कुल तेज नहीं था। बस एक त्वरित "ढूंढें और बदलें" और मैं ट्रैक पर वापस आ गया हूं!
जोर्जेन स्केचर फिशर

12
यह एक बेहतरीन जवाब है। एक बात थोड़ा अलग तरह से व्याख्या करने के लिए स्पष्ट करना, hasRole('xyz')वसंत सुरक्षा 4 उम्मीद में आपको शामिल करके ROLE_ उपसर्ग जबकि hasAuthority('xyz')उपसर्ग और मूल्यांकन करता है वास्तव में क्या है। मैं इस समाधान का इस्तेमाल किया पारित हो जाता है की उम्मीद नहीं है, लेकिन साथ समस्याओं में चल रहा था hasRole('OP_MY_PERMISSION')के बाद से ROLE_ उपसर्ग की जरूरत थी। इसके बजाय, मुझे hasAuthority('OP_MY_PERMISSION')उपसर्ग नहीं करने के बाद से उपयोग करना चाहिए था।
randal4

@james आप इस प्रश्न देख सकते हैं stackoverflow.com/questions/41500031/...
सौरभ कुमार

1
JSTL में springframework.org/security/tags <sec:authorize access="hasRole('ADMIN')">एक समान है<sec:authorize access="hasRole('ROLE_ADMIN')">
एलेक्स78191

1
हाँ। OP_ केवल एक मनमाना उपसर्ग है। कुछ वसंत कार्यान्वयन में ROLE_ का अपना विशेष अर्थ है।
जेम्स

9

AFAIK GrantedAuthority और भूमिकाएं वसंत सुरक्षा में समान हैं। GrantedAuthority की getAuthority () स्ट्रिंग भूमिका है (डिफ़ॉल्ट कार्यान्वयन SimpleGrantedAuthority के अनुसार)।

आपके मामले के लिए आप पदानुक्रमित भूमिका का उपयोग कर सकते हैं

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_ADMIN > ROLE_createSubUsers
            ROLE_ADMIN > ROLE_deleteAccounts 
            ROLE_USER > ROLE_viewAccounts
        </value>
    </property>
</bean>

आपके द्वारा खोजे जा रहे सटीक सोल नहीं, लेकिन आशा है कि यह मदद करता है

संपादित करें : अपनी टिप्पणी का जवाब दें

भूमिका वसंत-सुरक्षा में एक अनुमति की तरह है। हैरोले के साथ इंटरसेप्ट-यूआरएल का उपयोग करने से यह पता चलता है कि किस भूमिका / अनुमति के लिए किस ऑपरेशन की अनुमति दी जाती है।

जिस तरह से हम अपने आवेदन को संभालते हैं, हम उदाहरण के लिए प्रत्येक ऑपरेशन (या बाकी यूआरएल) के लिए अनुमति (यानी भूमिका) को परिभाषित करते हैं, उदाहरण के लिए view_account, delete_account, add_account आदि। फिर हम प्रत्येक उपयोगकर्ता के लिए तार्किक प्रोफाइल बनाते हैं जैसे एडमिन, गेस्ट_युसर, normal_user। प्रोफाइल बस तार्किक-तार्किक समूहन हैं, जो वसंत-सुरक्षा से स्वतंत्र हैं। जब एक नया उपयोगकर्ता जोड़ा जाता है, तो एक प्रोफ़ाइल उसे सौंपी जाती है (सभी अनुमत अनुमतियाँ)। अब जब कभी भी उपयोगकर्ता कुछ कार्रवाई करने की कोशिश करता है, तो उस कार्रवाई के लिए अनुमति / भूमिका उपयोगकर्ता की अनुमति के विरुद्ध जाँच की जाती है।

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


1
आपके सहयोग के लिए धन्यवाद। पदानुक्रम कुछ और दिखता है। जिस तरह से मैं अब ऐसा करने के बारे में सोच रहा हूं (यदि मुझे स्प्रिंग सिक्योरिटी का उपयोग करना है) दोनों की भूमिका और अधिकार एक ही सूची में संग्रहीत हैं और दोनों के लिए चेक करने के लिए हैड्रॉल प्रेडिकेट का उपयोग करें। इसके बारे में अधिक सोचना- यह शायद स्प्रिंग सिक्योरिटी के लोगों द्वारा जानबूझकर छोड़ा गया है? क्या रोल्स और विशेषाधिकार / प्राधिकरण - या अन्य प्राधिकरण अनुप्रयोगों की पूरी सूची पर hasRole का उपयोग करने के अलावा अन्य अवरोधक-यूआरएल का उपयोग करने की संभावना है। इसके अलावा, ROLE_ को उपसर्ग करने की क्या आवश्यकता है? क्या यह सम्मेलन है?
चिन्मय

7

इन अवधारणाओं के बीच के संबंध को समझने का एक और तरीका है कि एक ROLE को अधिकारियों के कंटेनर के रूप में व्याख्या करना।

प्राधिकारी ठीक-ठाक अनुमतियाँ हैं जो किसी विशिष्ट क्रिया को कभी-कभी विशिष्ट डेटा स्कोप या संदर्भ के साथ लक्षित करती हैं। उदाहरण के लिए, पढ़ें, लिखें, प्रबंधित करें, सूचना के दिए गए दायरे में अनुमतियों के विभिन्न स्तरों का प्रतिनिधित्व कर सकते हैं।

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

दूसरी ओर, रोल्स मोटे तौर पर अनुमतियों के एक समूह का प्रतिनिधित्व करते हैं। एक ROLE_READER में केवल पढ़ने या देखने का अधिकार होगा जबकि एक ROLE_EDITOR में Read और Write दोनों होंगे। रोल्स का उपयोग मुख्य रूप से http जैसे अनुरोध प्रसंस्करण के बाहरी क्षेत्र में पहली स्क्रीनिंग के लिए किया जाता है। ... .antMatcher (...)। हैरोल (ROLE_MANAGER)

अनुरोध के प्रक्रिया प्रवाह में गहरे लागू किए जा रहे प्राधिकरण अनुमति के एक महीन दाने वाले आवेदन की अनुमति देता है। उदाहरण के लिए, किसी उपयोगकर्ता के पास संसाधन को पहले स्तर तक पढ़ने की अनुमति हो सकती है, लेकिन केवल उप-संसाधन पर पढ़ें। ROLE_READER के पास प्रथम स्तर के संसाधन को संपादित करने के अपने अधिकार को रोकना होगा क्योंकि उसे इस संसाधन को संपादित करने के लिए लिखने की अनुमति की आवश्यकता है लेकिन एक @PreAuthorize इंटरसेप्टर उप-संसाधन को संपादित करने के लिए अपने अस्थायी ब्लॉक कर सकता है।

जेक


2

जैसा कि दूसरों ने उल्लेख किया है, मुझे लगता है कि भूमिकाओं के लिए कंटेनर अधिक ग्रैन्युलर अनुमतियों के लिए हैं।

हालाँकि मैंने पाया कि पदानुक्रम भूमिका कार्यान्वयन में इन दानेदार अनुमति के ठीक नियंत्रण का अभाव था।
इसलिए मैंने रिश्तों को संभालने और सुरक्षा के संदर्भ में अधिकारियों को अनुमति देने के लिए एक पुस्तकालय बनाया।

मेरे पास ऐप में अनुमतियों का एक सेट हो सकता है, जैसे क्रिएट, READ, UPDATE, DELETE, जो तब उपयोगकर्ता की भूमिका से जुड़े होते हैं।

या READ_POST, READ_PUBLISHED_POST, CREATE_POST, PUBLISH_POST जैसी अधिक विशिष्ट अनुमतियां

ये अनुमतियां अपेक्षाकृत स्थिर हैं, लेकिन उनके लिए भूमिकाओं का संबंध गतिशील हो सकता है।

उदाहरण -

@Autowired 
RolePermissionsRepository repository;

public void setup(){
  String roleName = "ROLE_ADMIN";
  List<String> permissions = new ArrayList<String>();
  permissions.add("CREATE");
  permissions.add("READ");
  permissions.add("UPDATE");
  permissions.add("DELETE");
  repository.save(new RolePermissions(roleName, permissions));
}

भूमिका के लिए इन अनुमतियों के संबंध को प्रबंधित करने के लिए आप एपीआई बना सकते हैं।

मैं किसी अन्य उत्तर को कॉपी / पेस्ट नहीं करना चाहता, इसलिए यहां SO पर अधिक संपूर्ण विवरण के लिए लिंक दिया गया है।
https://stackoverflow.com/a/60251931/1308685

मेरे कार्यान्वयन को फिर से उपयोग करने के लिए, मैंने एक रेपो बनाया। कृपया योगदान करने के लिए स्वतंत्र महसूस करें!
https://github.com/savantly-net/spring-role-permissions

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