2013-03-12 6 views
11

मैं एक स्प्रिंग प्रोजेक्ट में स्प्रिंग सुरक्षा जोड़ रहा हूं। सिस्टम का आर्किटेक्चर आरईएसटी है और उपयोगकर्ता विभिन्न संसाधनों तक पहुंच सकता है।@PreAuthorize विधि सुरक्षा नियमों और विधि पैरामीटर के साथ काम नहीं करता

मैं इस जानकारी के मालिकों और उपयोगकर्ताओं को व्यक्तिगत जानकारी तक पहुंच देना चाहता हूं। मैं साधारण शुरू कर दिया है: इस तरह उपयोगकर्ता प्रोफ़ाइल को छानने:

मेरी सेवा परत मैं विधि व्याख्या का उपयोग करना चाहता था और विधि पैरामीटर शामिल में ..

@PreAuthorize("hasRole('ROLE_ADMIN') or principal.userId == #id") 
public Usuario getUser(int id) throws DAOException { 
    ... 
} 

लेकिन इस सब पर काम नहीं कर रहा। (वेब परत) किसी भी उपयोगकर्ता सभी प्रोफ़ाइल देख सकते हैं (व्यवस्थापक और सभी उपयोगकर्ताओं को भी) इस URL अनुरोध किया जाता है:

@RequestMapping(value="/user/{uid}", method=RequestMethod.GET) 
    public ModelAndView getUser(@PathVariable int uid) throws DAOException { 
     userDAO = new UsuarioJPADAO(); 
     userService.setUsuarioDAO(userDAO); 

    return new ModelAndView("user", "user", userService.getUser(uid)); 
} 

यहाँ मेरी security.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/security" 
     xmlns:beans="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

<!-- Security Annotations --> 
    <global-method-security 
     pre-post-annotations="enabled"/> 

<http auto-config="true" use-expressions="true"> 
    <intercept-url pattern="/css/**" access="permitAll" /> 
    <intercept-url pattern="/images/**" access="permitAll" /> 
    <intercept-url pattern="/js/**" access="permitAll" /> 
    <intercept-url pattern="/favicon.ico" access="permitAll" /> 
    <intercept-url pattern="/login" access="permitAll" /> 

    <intercept-url pattern="/users" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="https://stackoverflow.com/users/page/*" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/customers" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/employees" access="hasRole('ROLE_ADMIN')" /> 

    <intercept-url pattern="/search/*" access="hasRole('ROLE_ADMIN')" /> 

    <intercept-url pattern="/*" access="hasAnyRole('ROLE_ADMIN, ROLE_EMPLOYEE, ROLE_PARTNER, ROLE_USER')" /> 
    <intercept-url pattern="/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <intercept-url pattern="/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <intercept-url pattern="/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <intercept-url pattern="/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <intercept-url pattern="/*/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <intercept-url pattern="/*/*/*/*/*/*/*" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" /> 
    <form-login login-page="/login" login-processing-url="/doLogin" 
       authentication-failure-url="/login?error" 
       username-parameter="username" password-parameter="password" 
       default-target-url="/default" /> 

    <logout invalidate-session="true" logout-success-url="/login?logout" logout-url="/logout"/> 
</http> 
<authentication-manager> 
    <authentication-provider user-service-ref="UsuarioService"> 
    </authentication-provider> 
</authentication-manager>  

मैं है Spring Security 3.1 book की जांच की है और स्पष्ट रूप से मेरी कॉन्फ़िगरेशन पुस्तक के सुझाव के रूप में है। मैंने अन्य स्टैक ओवरफ़्लो पोस्ट (here और here) पढ़े हैं लेकिन मुझे कोई भाग्य नहीं था।

अद्यतन: जोड़ा गया application-context.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p"  
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" 
     xmlns:security="http://www.springframework.org/schema/security" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:jee="http://www.springframework.org/schema/jee" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
     http://www.springframework.org/schema/tx 
     http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.1.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

    <context:annotation-config /> 

<context:component-scan base-package="com.pe.fs" /> 

<mvc:annotation-driven /> 

<mvc:resources mapping="/**" location="/" /> 

<mvc:interceptors> 
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> 
    <property name="paramName" value="lang" /> 
</bean> 
</mvc:interceptors> 

<!-- DataSource --> 
<bean id="jpaDataSource" class="oracle.jdbc.pool.OracleDataSource" 
    destroy-method="close" 
    p:driverType="oracle.jdbc.OracleDriver" 
    p:user="**********" 
    p:password="**********" 
    p:uRL="jdbc:oracle:thin:@localhost:1521:XE" 
/> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property> 
    <property name="persistenceUnitName" value="freesunPU" /> 
    <property name="dataSource" ref="jpaDataSource" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="showSql" value="false" /> 
     </bean> 
    </property> 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> 
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory" /> 

<tx:annotation-driven mode="aspectj"/> 

<context:load-time-weaver aspectj-weaving="autodetect" /> 

अद्यतन: मैं पोम और कोई बदलाव नहीं करने के लिए spring-security-aspects जोड़ लिया है। उत्तरों में सुझाए गए अन्य परिवर्तनों का परीक्षण किया गया है लेकिन एनोटेशन जैसे @PreAuthorize अभी भी काम नहीं कर रहे हैं। सीएनए यह संदर्भों के बीच एक समस्या है? पहलूजे का कारण क्या हो सकता है?

मैं क्या गलत कर रहा हूं?

public interface UserService extends UserDetailsService { 
    Usuario getUser(int id) throws DAOException 
} 

अपने उपयोगकर्ता सेवा में लागू करें और दोबारा कोशिश:

+0

आपका 'usuario getUser (पूर्णांक आईडी)' विधि कुछ इंटरफ़ेस में परिभाषित किया गया है? डिफ़ॉल्ट रूप से एनोटेशन इस तरह का काम कर सकते हैं नहीं (JDK proxieas क्रम में प्राधिकरण चेकों को जोड़ने के लिए उपयोग किया जाता है और वे केवल इंटरफ़ेस तरीकों लक्षित कर सकते हैं) –

+0

@MaksymDemidas नहीं। मेरे UsuarioService UserDetailsService लागू करता है। मैं अपने स्वयं के UsuarioDetails क्लास के साथ भी काम कर रहा हूं जो मेरे डोमेन Usuario को बढ़ाता है और उपयोगकर्ता विवरण – Spacemonkey

+0

wft man लागू करता है? :) <अवरोधन-यूआरएल ढांचा = "/ */*/*/*/*" पहुँच = "hasAnyRole ('ROLE_USER, ROLE_ADMIN')" /> परिवर्तन ""/*/*/*/*/* "" करने के लिए "/ **" – Yura

उत्तर

9

अंततः मुझे समाधान मिला। SO में मुझे कुछ उपयोगी उत्तर मिले। here और here देखें।

मैं application-context.xml जो अपनी सेवाओं के संदर्भ है global-method-security ले जाया गया।

<security:global-method-security 
    mode="aspectj" 
    secured-annotations="enabled" 
    jsr250-annotations="disabled" 
    pre-post-annotations="enabled"/> 

कहाँ mode="aspectj" जावाडोक के रूप में कहते हैं:

... कि AspectJ डिफ़ॉल्ट स्प्रिंग AOP के बजाय इस्तेमाल किया जाना चाहिए निर्दिष्ट करने के लिए इस्तेमाल किया जा सकता। यदि सेट किया गया है, तो सुरक्षित कक्षाओं को वसंत-सुरक्षा-पहलुओं मॉड्यूल से एनोटेशन सुरक्षा योग्यता के साथ बुना जाना चाहिए।

बेशक

, मैं पोम spring-security-aspects में शामिल किया है:

<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-aspects</artifactId> 
    <version>3.1.3.RELEASE</version> 
</dependency> 
+0

यह देखकर खुशी हुई कि आपको समाधान मिला! –

+0

प्रिय @MaksymDemidas, आपकी मदद के लिए धन्यवाद। – Spacemonkey

+0

वैश्विक-विधि-सुरक्षा को मेरी समस्या हल करती है। http://docs.spring.io/spring-security/site/faq/faq.html#faq-method-security-in-web-context – user227353

0

नए इंटरफ़ेस जोड़ें। वसंत जेडीके प्रॉक्सी का उपयोग करके प्राधिकृत जांच अनुरोधों को जोड़ने में सक्षम हो जाएगा।

आप स्प्रिंग Javassist या यहाँ तक कि AspectJ.In की तरह कुछ और दिग्गज पुस्तकालयों का उपयोग करने के लिए इस मामले इंटरफ़ेस आवश्यक नहीं होगा कॉन्फ़िगर कर सकते हैं एक और विकल्प के रूप में।

संपादित करें। सुनिश्चित करें कि global-method-security आपकी उपयोगकर्ता सेवा बीन के साथ उसी वसंत संदर्भ में घोषित किया गया है।

+0

इंटरफ़ेस जोड़ते समय काम नहीं कर रहा है .. क्या मुझे इस विधि को एनोटेट करना चाहिए जैसा मैंने अपनी पोस्ट में किया था, इंटरफ़ेस में नहीं, है ना? – Spacemonkey

+0

हाँ, एनोटेशन सामान्य रूप से कार्यान्वयन पक्ष –

+1

पर लागू होते हैं अपने वसंत एक्सएमएल दिखाने करें। आपके पास दो वसंत संदर्भ हो सकते हैं (सेम के लिए और स्प्रिंग एमवीसी के लिए)। क्या आप सुनिश्चित हैं कि आपकी वैश्विक-विधि-सुरक्षा elemnt को आपकी उपयोगकर्ता सेवा के समान संदर्भ में परिभाषित किया गया है? –

0

वैकल्पिक तरीका यह काम करने के लिए अपने security.xml में निम्न कोड जोड़ने के लिए है

<intercept-url pattern="/user/**" access="hasRole('ROLE_ADMIN')" /> 

यह होगा सुनिश्चित करें कि केवल व्यवस्थापक पैटर्न/उपयोगकर्ता/से शुरू होने वाले संसाधनों तक पहुंच सकता है।

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