2016-01-24 81 views
0

环境:Spring MVC的REST +弹簧安全+基本身份验证

春4.1

春季安全4.0

问题:

我开发使用Spring一个简单的REST服务4.1。并使用Spring安全性进行身份验证。 我正在使用HTTP基本验证。

问题是,即使所有配置都正确,基本身份验证仍无法正常工作。 我正在使用邮递员向服务器发送请求。 REST客户端可以调用没有授权标头的REST控制器方法。 该方法在没有任何验证错误的情况下成功执行。

由于我使用Tomcat 6,因此我没有使用servlet 3.0功能,所以web.xml确实存在。 已在REST控制器层上使用@Secured批注实施了方法级安全性。

任何人都可以请求帮助我去哪里错了吗?

代码:

web.xml中

<web-app> 
    <display-name>Archetype Created Web Application</display-name> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <listener> 
     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
    </listener> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/mvc-dispatcher-servlet-security.xml</param-value> 
    </context-param> 

    <servlet> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> 
     </init-param>  
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <filter> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <url-pattern>/*</url-pattern> 
     <dispatcher>FORWARD</dispatcher> 
     <dispatcher>REQUEST</dispatcher>  
    </filter-mapping> 

</web-app> 

MVC-servlet的调度员security.xml文件:

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

    <http use-expressions="true" create-session="stateless"> 
     <http-basic/> 
     <csrf disabled="true"/> 
    </http> 

    <global-method-security secured-annotations="enabled"/> 

    <authentication-manager> 
     <authentication-provider> 
      <user-service> 
       <user name="XYZ" password="12345" authorities="ROLE_USER" /> 
      </user-service> 
     </authentication-provider> 
    </authentication-manager> 

</beans:beans> 

MVC-调度-servlet.xml中:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <!-- Specifying base package of the Components like Controller, Service, DAO --> 
    <context:component-scan base-package="org.ngo" /> 
    <!-- Getting Database properties --> 
    <context:property-placeholder location="classpath:application.properties"/> 

    <mvc:annotation-driven/> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="${jdbc.driverClassName}" /> 
     <property name="url" value="${jdbc.url}" /> 
     <property name="username" value="${jdbc.username}" /> 
     <property name="password" value="${jdbc.password}" /> 
    </bean> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource"> 
      <ref bean="dataSource" /> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
       <prop key="hibernate.show_sql">true</prop>    
      </props> 
     </property> 
     <property name="packagesToScan" value="org.ngo.abhishek.entity"></property> 
    </bean> 

    <!-- Transaction --> 
    <bean id="transactionManager" 
     class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager" /> 
</beans> 

其余控制器:

@RestController 
@RequestMapping("/abhishek") 
public class AbhishekController { 

    @Autowired 
    private AbhisheskService abhishekService; 

    @RequestMapping(method=RequestMethod.POST,consumes="application/json") 
    @Secured("ROLE_USER") 
    public ResponseEntity<Boolean> getUserById(@RequestBody List<AbhishekDTO> abhishekDtoList) { 

     boolean flag = this.abhishekService.createAbhishek(abhishekDtoList);  
     return new ResponseEntity<Boolean>(flag, HttpStatus.OK);  
    } 

} 

回答

1

从Stiletto得到线索后,我删除了@Secured("ROLE_USER")并使用基于表达式的安全检查。它工作(使用拦截url)。所以问题出在了@Secured的位置。

由于@Secured处于调度程序servlet上下文(按照Spring原理的子上下文),并且spring安全范围位于applicationContext(父上下文)中,所以spring安全性被忽略。

<security:global-method-security secured-annotations="enabled"/>置于mvc-dispatcher-servlet.xml解决了这个问题。

SO上的相似问题:Spring MVC, Method level security

1

我想你的设置,它为我工作。由于你没有提供你所有的代码,我最好的猜测是你的控制器的组件扫描没有发生,或者你的浏览器缓存并发送基本认证凭证,但你没有意识到它。

+0

感谢您的回复。我会检查这两件事 – Atul