简体   繁体   English

带有Spring Security的Spring MVC一个简单示例不起作用

[英]Spring MVC with Spring Security a simple example does not work

I'm having trouble with setting up a simple spring security. 我在设置简单的Spring Security时遇到了麻烦。 I'm trying to set up the most simple example possible with the configuration below. 我正在尝试通过以下配置设置最简单的示例。 It seems that the request never gets intercepted? 似乎请求从未被拦截?

Project structure 项目结构

在此处输入图片说明

BasicController.java BasicController.java

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class BasicController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello";
    }

}

web.xml web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

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

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/spring/context.xml
      /WEB-INF/spring/security.xml
    </param-value>
  </context-param>

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

  <servlet>
    <servlet-name>web</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>web</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>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter>

</web-app>

security.xml security.xml

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

    <security:http auto-config="true" use-expressions="true" >
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
        <security:http-basic />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="admin" password="admin" authorities="ROLE_USER" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

context.xml context.xml

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

    <context:component-scan base-package="controller" />

    <mvc:annotation-driven />

    <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />

    <bean id="templateLoader" class="de.neuland.jade4j.spring.template.SpringTemplateLoader">
        <property name="basePath" value="/WEB-INF/views/" />
    </bean>

    <bean id="jadeConfiguration" class="de.neuland.jade4j.JadeConfiguration">
        <property name="prettyPrint" value="false" />
        <property name="caching" value="false" />
        <property name="templateLoader" ref="templateLoader" />
    </bean>

    <bean id="viewResolver" class="de.neuland.jade4j.spring.view.JadeViewResolver">
        <property name="configuration" ref="jadeConfiguration" />
        <property name="renderExceptions" value="true" />
    </bean>

</beans>

Logs 日志

It evident that both spring configuration files are being read and security is mapped onto Creating access control expression attribute 'isAuthenticated()' for /** and yet the page is not protected! 显然,两个Spring配置文件都已被读取,并且安全性已映射到Creating access control expression attribute 'isAuthenticated()' for /** ,但是该页面不受保护!

Listening for transport dt_socket at address: 63383
Connected to the target VM, address: '127.0.0.1:63383', transport: 'socket'
Nov 25, 2016 11:50:42 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
Nov 25, 2016 11:50:42 AM org.springframework.web.context.support.XmlWebApplicationContext prepareRefresh
INFO: Refreshing Root WebApplicationContext: startup date [Fri Nov 25 11:50:42 GMT 2016]; root of context hierarchy
Nov 25, 2016 11:50:42 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/context.xml]
Nov 25, 2016 11:50:43 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/security.xml]
Nov 25, 2016 11:50:43 AM org.springframework.security.core.SpringSecurityCoreVersion performVersionChecks
INFO: You are running with Spring Security Core 4.2.0.RELEASE
Nov 25, 2016 11:50:43 AM org.springframework.security.config.SecurityNamespaceHandler <init>
INFO: Spring Security 'config' module version is 4.2.0.RELEASE
Nov 25, 2016 11:50:43 AM org.springframework.security.config.http.FilterInvocationSecurityMetadataSourceParser parseInterceptUrlsForFilterInvocationRequestMap
INFO: Creating access control expression attribute 'isAuthenticated()' for /**
Nov 25, 2016 11:50:43 AM org.springframework.security.config.http.AuthenticationConfigBuilder createLoginPageFilterIfNeeded
INFO: No login page configured. The default internal one will be used. Use the 'login-page' attribute to set the URL of the login page.
Nov 25, 2016 11:50:43 AM org.springframework.security.config.http.HttpSecurityBeanDefinitionParser checkFilterChainOrder
INFO: Checking sorted filter chain: [Root bean: class [org.springframework.security.web.context.SecurityContextPersistenceFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 200, Root bean: class [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 400, Root bean: class [org.springframework.security.web.header.HeaderWriterFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 500, Root bean: class [org.springframework.security.web.csrf.CsrfFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 700, Root bean: class [org.springframework.security.web.authentication.logout.LogoutFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 800, <org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0>, order = 1200, Root bean: class [org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1400, Root bean: class [org.springframework.security.web.authentication.www.BasicAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1600, Root bean: class [org.springframework.security.web.savedrequest.RequestCacheAwareFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1700, Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.security.config.http.HttpConfigurationBuilder$SecurityContextHolderAwareRequestFilterBeanFactory#0; factoryMethodName=getBean; initMethodName=null; destroyMethodName=null, order = 1800, Root bean: class [org.springframework.security.web.authentication.AnonymousAuthenticationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2100, Root bean: class [org.springframework.security.web.session.SessionManagementFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2200, Root bean: class [org.springframework.security.web.access.ExceptionTranslationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 2300, <org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0>, order = 2400]
Nov 25, 2016 11:50:44 AM org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
INFO: Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
Nov 25, 2016 11:50:45 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/hello],methods=[GET]}" onto public java.lang.String controller.BasicController.hello()
Nov 25, 2016 11:50:45 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Fri Nov 25 11:50:42 GMT 2016]; root of context hierarchy
Nov 25, 2016 11:50:45 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Fri Nov 25 11:50:42 GMT 2016]; root of context hierarchy
Nov 25, 2016 11:50:46 AM org.springframework.security.web.DefaultSecurityFilterChain <init>
INFO: Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.springframework.security.web.context.SecurityContextPersistenceFilter@4a5905d9, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1a3e5f23, org.springframework.security.web.header.HeaderWriterFilter@6293e39e, org.springframework.security.web.csrf.CsrfFilter@365553de, org.springframework.security.web.authentication.logout.LogoutFilter@34a0ef00, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@5c0f79f0, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@21fdfefc, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@3daa82be, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@ec1b2e4, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@29a69a35, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@67e28be3, org.springframework.security.web.session.SessionManagementFilter@e344ad3, org.springframework.security.web.access.ExceptionTranslationFilter@de18f63, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@108bdbd8]
Nov 25, 2016 11:50:47 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 4797 ms
Nov 25, 2016 11:50:47 AM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'web': initialization started
Nov 25, 2016 11:50:47 AM org.springframework.web.context.support.XmlWebApplicationContext prepareRefresh
INFO: Refreshing WebApplicationContext for namespace 'web-servlet': startup date [Fri Nov 25 11:50:47 GMT 2016]; parent: Root WebApplicationContext
Nov 25, 2016 11:50:47 AM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'web': initialization completed in 25 ms

I preferably want to use XML configuration rather than java. 我最好希望使用XML配置而不是Java。 However, if I try to use an annotation @Secured or @PreAuthorize I will get an exception AuthenticationCredentialsNotFoundException when I try to access the page: 但是,如果尝试使用注释@Secured@PreAuthorize ,则在尝试访问页面时会收到AuthenticationCredentialsNotFoundException异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:976)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:856)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:841)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:837)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:524)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:379)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:223)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    at controller.BasicController$$EnhancerBySpringCGLIB$$bf19eb0f.hello(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:220)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:964)

For the context part, i noticed that you forgot to specify the path to the actual file (spring config file): <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> 对于上下文部分,我注意到您忘记指定实际文件(spring配置文件)的路径: <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param>

You simply have to replace that part to the new one : 您只需要将该部分替换为新的部分:

<init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/spring/context.xml</param-value>
</init-param>

I originally used IntelliJ with Jetty plugin which does not work. 我最初将IntelliJ与Jetty插件一起使用不起作用。

I was able to successfully run the Spring security on Tomcat server . 我能够在Tomcat服务器上成功运行Spring安全性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM