2011-07-31 12 views
20

स्प्रिंग सुरक्षा में हम नीचे के रूप में यूआरएल के लिए पहुँच को परिभाषित करने के अवरोधन-यूआरएल टैग इस्तेमाल करें:वसंत सुरक्षा में गतिशील रूप से <intercept-url> एक्सेस विशेषता मान का निर्धारण कैसे करें?

<intercept-url pattern="/**" access="ROLE_ADMIN" /> 
<intercept-url pattern="/student" access="ROLE_STUDENT" /> 

यह कठिन applicationContext-security.xml में कोडित है। मैं इसके बजाय डेटाबेस तालिका से एक्सेस मानों को पढ़ना चाहता हूं। मैंने अपना खुद का UserDetailsService परिभाषित किया है और मैंने डेटाबेस से लॉग इन उपयोगकर्ता के लिए भूमिकाएं पढ़ी हैं। मैं रनटाइम के दौरान यूआरएल पैटर्न में इन भूमिकाओं को कैसे आवंटित करूं?

+0

यह सहायक हो सकती:: https:

<intercept-url pattern="/**/**" access="#{@customAuthenticationProvider.returnStringMethod}" /> <intercept-url pattern="/**" access="#{@customAuthenticationProvider.returnStringMethod}" /> 

customAuthenticationProvider बनाने विधि एक सेम

<beans:bean id="customAuthenticationProvider" class="package.security.CustomAuthenticationProvider" /> 

CustomAuthenticationProvider कक्षा में है //github.com/srinivas1918/spring-security-dynamic प्राधिकरण-और-प्रमाणीकरण –

उत्तर

18

वसंत-सुरक्षा में FilterInvocationSecurityMetadataSourceParser वर्ग अवरोधन-यूआरएल टैग पार्स करके ExpressionBasedFilterInvocationSecurityMetadataSource के उदाहरण बनाता है, कि DefaultFilterInvocationSecurityMetadataSource कि FilterInvocationSecurityMetadataSource कि SecurityMetadataSource फैली लागू करता फैली (Ctrl/Cmd + स्रोत कोड के साथ एसटीएस में Shift + T कोशिश)।

मैं क्या था कि FilterInvocationSecurityMetadataSource लागू करता है एक कस्टम वर्ग, OptionsFromDataBaseFilterInvocationSecurityMetadataSource तैयार करना है। मैंने समर्थन() विधि और कुछ ऐसा करने के लिए urlMatcher का उपयोग करने के लिए डिफ़ॉल्ट के रूप में DefaultFilterInvocationSecurityMetadataSource का उपयोग किया।

फिर आप इन तरीकों को लागू करने के कार्य करने होंगे:

  • संग्रह getAttributes (वस्तु वस्तु), जहाँ आप डेटाबेस के लिए उपयोग कर सकते हैं, 'वस्तु' के लिए खोज प्राप्त करने के लिए (सामान्य रूप से उपयोग करने के लिए यूआरएल) सुरक्षित किया जा रहा अनुमति ConfigAttribute के (सामान्य रूप से भूमिका है)

  • बूलियन का समर्थन करता है (कक्षा clazz)

  • संग्रह getAllConfigAttributes()

बाद में सावधान रहें, क्योंकि इसे स्टार्टअप पर बुलाया जाता है और शायद इस समय आपके द्वारा उपयोग किए जा रहे कार्यों के आधार पर डेटा स्रोत या दृढ़ता संदर्भ के साथ स्वचालित रूप से कॉन्फ़िगर नहीं किया गया है)। वेब वातावरण में समाधान web.xml में applicationContext.xml को लोड करने के लिए webCxxt में कॉन्फ़िगरेशन कॉन्फ़िगर करना है। कॉन्टैक्ट-सुरक्षा.एक्सएमएल

अंतिम चरण इस बीन को लोड करने के लिए applicationContext-security.xml को कस्टमाइज़ करना है।

कर रही के लिए, मैं सुरक्षा नाम स्थान के बजाय इस फ़ाइल में नियमित सेम का प्रयोग किया:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> 
    <filter-chain-map path-type="ant"> 
     <filter-chain pattern="/images/*" filters="none" /> 
     <filter-chain pattern="/resources/**" filters="none" /> 
     <filter-chain pattern="/**" filters=" 
     securityContextPersistenceFilter, 
     logoutFilter, 
     basicAuthenticationFilter, 
     exceptionTranslationFilter, 
     filterSecurityInterceptor" 
    /> 
    </filter-chain-map> 
</beans:bean> 

आप सभी संबंधित सेम परिभाषित करने के लिए किया है। उदाहरण के लिए:

<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> 
    <beans:property name="authenticationManager" ref="authenticationManager"></beans:property> 
    <beans:property name="accessDecisionManager" ref="affirmativeBased"></beans:property> 
    <beans:property name="securityMetadataSource" ref="optionsFromDataBaseFilterInvocationSecurityMetadataSource"></beans:property> 
    <beans:property name="validateConfigAttributes" value="true"/></beans:bean> 

मुझे पता है कि एक अच्छी तरह से समझाया जवाब नहीं है, लेकिन यह के रूप में ऐसा लगता है के रूप में मुश्किल नहीं है।

बस वसंत स्रोत का आधार के रूप में उपयोग करें और आप जो चाहते हैं उसे प्राप्त करेंगे।

आपके डेटाबेस में डेटा के साथ डिबगिंग, आपको बहुत मदद करेगा।

+0

नमस्ते मैं एक ही चीज़ को प्राप्त करने की कोशिश कर रहा हूं लेकिन struts2 के साथ। वसंत सुरक्षा 3.1 के माध्यम से चला गया लेकिन struts2 के साथ एकीकृत करने के बारे में पर्याप्त विचार नहीं मिल सका। क्या आप struts2 के साथ एकीकृत करने के लिए कुछ बुनियादी विचार देने पर ध्यान देंगे? – SunJCarkeY

+0

यह उदाहरण वसंत के पुराने संस्करण के तहत है। वसंत-सुरक्षा 3.2 के तहत मैं इसे कैसे कर सकता हूं? – ajaristi

2

मुझे एक ही समस्या है, मूल रूप से मैं अन्य springsecurity कॉन्फ़िगरेशन अनुभाग से इंटरसेप्ट-यूआरएल की सूची को अलग रखना चाहता हूं, पहले उत्पाद कॉन्फ़िगरेशन (कोर, प्लगइन)) विन्यास।

इस समस्या से संबंधित वसंत के जेआईआरए में proposal है।

मैं वसंत सुरक्षा नामस्थान का उपयोग करने के लिए छोड़ना नहीं चाहता, इसलिए मैं इससे निपटने के लिए कुछ संभावित समाधानों पर विचार कर रहा था।

गतिशील रूप से बनाए गए इंटरसेप्ट-यूआरएल की सूची रखने के लिए आपको FilterSecurityInterceptor में securitymetadatasource ऑब्जेक्ट को इंजेक्ट करना होगा। का उपयोग springsecurity स्कीमा FilterSecurityInterceptor के कहने HttpBuilder वर्ग द्वारा बनाई गई है और स्कीमा विन्यास फाइल में परिभाषित संपत्ति के रूप में securitymetadatasource पारित करने के लिए कोई रास्ता नहीं है, के रूप में वैकल्पिक हल की तरह का उपयोग कर के रूप में कम है, जो हो सकता है नहीं है:

  • FilterSecurityInterceptor से पहले निष्पादित करने के लिए एक कस्टम फ़िल्टर को परिभाषित करें, इस फ़िल्टर में वसंत संदर्भ द्वारा फ़िल्टर SecurityInterceptor (एक अद्वितीय http अनुभाग परिभाषित किया गया है) को पुनर्प्राप्त करने और सुरक्षा मेटाडेटासोर्स उदाहरण को इंजेक्ट करने के लिए;
  • ऊपर जैसा ही है लेकिन हैंडलरइंटरसेप्टर में।

आपको क्या लगता है?

1

यह समाधान मैंने अन्य वसंत सुरक्षा कॉन्फ़िगरेशन से इंटरसेप्ट-यूआरएल प्रविष्टियों की सूची को विभाजित करने के लिए लागू किया है।

<security:custom-filter ref="parancoeFilterSecurityInterceptor" 
     before="FILTER_SECURITY_INTERCEPTOR" /> 
........ 

<bean id="parancoeFilterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor" > 
    <property name="authenticationManager" ref="authenticationManager"/> 
    <property name="accessDecisionManager" ref="accessDecisionManager"/> 
    <property name="securityMetadataSource" ref="securityMetadataSource"/> 
</bean> 

बीन सुरक्षा मेटाडेटा स्रोत को या तो एक ही कॉन्फ़िगरेशन फ़ाइल या किसी अन्य कॉन्फ़िगरेशन फ़ाइल में रखा जा सकता है।

<security:filter-security-metadata-source 
    id="securityMetadataSource" use-expressions="true"> 
    <security:intercept-url pattern="/admin/**" 
     access="hasRole('ROLE_ADMIN')" /> 
</security:filter-security-metadata-source> 
बेशक आप इंटरफ़ेस FilterInvocationSecurityMetadataSource को लागू करने से अपने स्वयं के securityMetadataSource सेम लागू करने के लिए तय कर सकते हैं के

। कुछ इस तरह:

<bean id="securityMetadataSource" class="mypackage.MyImplementationOfFilterInvocationSecurityMetadataSource" /> 

आशा इस मदद करता है।

+0

मैं एक ही समाधान के साथ समाप्त हुआ। यह एक दयालुता है कि परिभाषा को विभाजित करने का कोई आसान तरीका नहीं है। –

4

वास्तव में, वसंत सुरक्षा 3.2 http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/faq.html#faq-dynamic-url-metadata

लेकिन, यह संभव है (लेकिन सुंदर नहीं है) एक कस्टम accessDecisionManager साथ नाम स्थान में http तत्व का उपयोग के अनुसार ऐसा करने के लिए प्रोत्साहित नहीं करते ..

config चाहिए हो:

<http pattern="/login.action" security="none"/> 
<http pattern="/media/**" security="none"/> 

<http access-decision-manager-ref="accessDecisionManager" > 
    <intercept-url pattern="/**" access="ROLE_USER"/> 
    <form-login login-page="/login.action" 
       authentication-failure-url="/login?error=1" 
       default-target-url="/console.action"/> 
    <logout invalidate-session="true" delete-cookies="JSESIONID"/> 
    <session-management session-fixation-protection="migrateSession"> 
     <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.action"/> 
    </session-management> 

    <!-- NO ESTA FUNCIONANDO, los tokens no se ponen en el request! 
    <csrf /> 
    --> 

</http> 
<authentication-manager> 
    <authentication-provider> 
     <user-service> 
      <user name="test" password="test" authorities="ROLE_USER" /> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 

<beans:bean id="accessDecisionManager" class="openjsoft.core.services.security.auth.CustomAccessDecisionManager"> 
    <beans:property name="allowIfAllAbstainDecisions" value="false"/> 
    <beans:property name="decisionVoters"> 
    <beans:list> 
     <beans:bean class="org.springframework.security.access.vote.RoleVoter"/> 
    </beans:list> 
    </beans:property> 
</beans:bean> 

CustomAccessDecisionManager होना चाहिए ...

public class CustomAccessDecisionManager extends AbstractAccessDecisionManager { 
... 

public void decide(Authentication authentication, Object filter, 
     Collection<ConfigAttribute> configAttributes) 
     throws AccessDeniedException, InsufficientAuthenticationException { 

    if ((filter == null) || !this.supports(filter.getClass())) { 
     throw new IllegalArgumentException("Object must be a FilterInvocation"); 
    } 

    String url = ((FilterInvocation) filter).getRequestUrl(); 
    String contexto = ((FilterInvocation) filter).getRequest().getContextPath(); 

    Collection<ConfigAttribute> roles = service.getConfigAttributesFromSecuredUris(contexto, url); 



    int deny = 0; 

    for (AccessDecisionVoter voter : getDecisionVoters()) { 
     int result = voter.vote(authentication, filter, roles); 

     if (logger.isDebugEnabled()) { 
      logger.debug("Voter: " + voter + ", returned: " + result); 
     } 

     switch (result) { 
     case AccessDecisionVoter.ACCESS_GRANTED: 
      return; 

     case AccessDecisionVoter.ACCESS_DENIED: 

      deny++; 

      break; 

     default: 
      break; 
     } 
    } 

    if (deny > 0) { 
     throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied", 
       "Access is denied")); 
    } 

    // To get this far, every AccessDecisionVoter abstained 
    checkAllowIfAllAbstainDecisions(); 
} 

... 
} 

कहाँ getConfigAttributesFromSecuredUris विशिष्ट यूआरएल

0

के लिए प्रपत्र डीबी डी भूमिकाओं को पुनः प्राप्त यह है कि यह कैसे स्प्रिंग सुरक्षा 3.2 में किया जा सकता है:

@Configuration 
@EnableWebMvcSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Bean 
    public SecurityConfigDao securityConfigDao() { 
     SecurityConfigDaoImpl impl = new SecurityConfigDaoImpl() ; 
     return impl ; 
    } 



    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     /* get a map of patterns and authorities */ 
     Map<String,String> viewPermissions = securityConfigDao().viewPermissions() ; 

     ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry interceptUrlRegistry = http 
     .authorizeRequests().antMatchers("/publicAccess/**") 
     .permitAll(); 

     for (Map.Entry<String, String> entry: viewPermissions.entrySet()) { 
      interceptUrlRegistry.antMatchers(entry.getKey()).hasAuthority(entry.getValue()); 
     } 

     interceptUrlRegistry.anyRequest().authenticated() 
     .and() 
     ... 
     /* rest of the configuration */ 
    } 
} 
1

एक सरल समाधान है कि मेरे लिए काम करता है।

public synchronized String getReturnStringMethod() 
{ 
    //get data from database (call your method) 

    if(condition){ 
     return "IS_AUTHENTICATED_ANONYMOUSLY"; 
    } 
    return "ROLE_ADMIN,ROLE_USER"; 
}