Spring mvc 当发送请求时,SpringOAuth在响应体中包含stacktrace
在OAuth 2代码中,一个错误(例如使用无效的令牌值请求刷新令牌)最终生成一个包含堆栈跟踪的响应,我看不到配置或禁用此额外信息的方法 当我点击api url时,我得到了下面的堆栈跟踪,而它应该只显示401个未经授权的urlSpring mvc 当发送请求时,SpringOAuth在响应体中包含stacktrace,spring-mvc,spring-security,oauth-2.0,spring-security-oauth2,spring-rest,Spring Mvc,Spring Security,Oauth 2.0,Spring Security Oauth2,Spring Rest,在OAuth 2代码中,一个错误(例如使用无效的令牌值请求刷新令牌)最终生成一个包含堆栈跟踪的响应,我看不到配置或禁用此额外信息的方法 当我点击api url时,我得到了下面的堆栈跟踪,而它应该只显示401个未经授权的url "stackTrace": [ { "methodName": "translate", "fileName": "DefaultWebResponseExceptionTranslator.java", "lineNumber": 53, "clas
"stackTrace": [
{
"methodName": "translate",
"fileName": "DefaultWebResponseExceptionTranslator.java",
"lineNumber": 53,
"className": "org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator",
"nativeMethod": false
},
{
"methodName": "doHandle",
"fileName": "AbstractOAuth2SecurityExceptionHandler.java",
"lineNumber": 59,
"className": "org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler",
"nativeMethod": false
},
{
"methodName": "commence",
"fileName": "OAuth2AuthenticationEntryPoint.java",
"lineNumber": 54,
"className": "org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint",
"nativeMethod": false
},
{
"methodName": "sendStartAuthentication",
"fileName": "ExceptionTranslationFilter.java",
"lineNumber": 186,
"className": "org.springframework.security.web.access.ExceptionTranslationFilter",
"nativeMethod": false
},
{
"methodName": "handleSpringSecurityException",
"fileName": "ExceptionTranslationFilter.java",
"lineNumber": 161,
"className": "org.springframework.security.web.access.ExceptionTranslationFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "ExceptionTranslationFilter.java",
"lineNumber": 131,
"className": "org.springframework.security.web.access.ExceptionTranslationFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "SessionManagementFilter.java",
"lineNumber": 103,
"className": "org.springframework.security.web.session.SessionManagementFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "SecurityContextHolderAwareRequestFilter.java",
"lineNumber": 154,
"className": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "RequestCacheAwareFilter.java",
"lineNumber": 45,
"className": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "OAuth2AuthenticationProcessingFilter.java",
"lineNumber": 131,
"className": "org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilterInternal",
"fileName": "WebAsyncManagerIntegrationFilter.java",
"lineNumber": 50,
"className": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "OncePerRequestFilter.java",
"lineNumber": 107,
"className": "org.springframework.web.filter.OncePerRequestFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "SecurityContextPersistenceFilter.java",
"lineNumber": 87,
"className": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 342,
"className": "org.springframework.security.web.FilterChainProxy$VirtualFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilterInternal",
"fileName": "FilterChainProxy.java",
"lineNumber": 192,
"className": "org.springframework.security.web.FilterChainProxy",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterChainProxy.java",
"lineNumber": 160,
"className": "org.springframework.security.web.FilterChainProxy",
"nativeMethod": false
},
{
"methodName": "invokeDelegate",
"fileName": "DelegatingFilterProxy.java",
"lineNumber": 344,
"className": "org.springframework.web.filter.DelegatingFilterProxy",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "DelegatingFilterProxy.java",
"lineNumber": 261,
"className": "org.springframework.web.filter.DelegatingFilterProxy",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "FilterInstanceWrapper.java",
"lineNumber": 195,
"className": "com.ibm.ws.webcontainer.filter.FilterInstanceWrapper",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "WebAppFilterChain.java",
"lineNumber": 91,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterChain",
"nativeMethod": false
},
{
"methodName": "doFilter",
"fileName": "WebAppFilterManager.java",
"lineNumber": 928,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterManager",
"nativeMethod": false
},
{
"methodName": "invokeFilters",
"fileName": "WebAppFilterManager.java",
"lineNumber": 1025,
"className": "com.ibm.ws.webcontainer.filter.WebAppFilterManager",
"nativeMethod": false
},
{
"methodName": "handleRequest",
"fileName": "WebApp.java",
"lineNumber": 3748,
"className": "com.ibm.ws.webcontainer.webapp.WebApp",
"nativeMethod": false
},
{
"methodName": "handleRequest",
"fileName": "WebGroup.java",
"lineNumber": 304,
"className": "com.ibm.ws.webcontainer.webapp.WebGroup",
"nativeMethod": false
},
{
"methodName": "handleRequest",
"fileName": "WebContainer.java",
"lineNumber": 962,
"className": "com.ibm.ws.webcontainer.WebContainer",
"nativeMethod": false
},
{
"methodName": "handleRequest",
"fileName": "WSWebContainer.java",
"lineNumber": 1662,
"className": "com.ibm.ws.webcontainer.WSWebContainer",
"nativeMethod": false
},
{
"methodName": "ready",
"fileName": "WCChannelLink.java",
"lineNumber": 195,
"className": "com.ibm.ws.webcontainer.channel.WCChannelLink",
"nativeMethod": false
},
{
"methodName": "handleDiscrimination",
"fileName": "HttpInboundLink.java",
"lineNumber": 459,
"className": "com.ibm.ws.http.channel.inbound.impl.HttpInboundLink",
"nativeMethod": false
},
{
"methodName": "handleNewRequest",
"fileName": "HttpInboundLink.java",
"lineNumber": 526,
"className": "com.ibm.ws.http.channel.inbound.impl.HttpInboundLink",
"nativeMethod": false
},
{
"methodName": "processRequest",
"fileName": "HttpInboundLink.java",
"lineNumber": 312,
"className": "com.ibm.ws.http.channel.inbound.impl.HttpInboundLink",
"nativeMethod": false
},
{
"methodName": "ready",
"fileName": "HttpInboundLink.java",
"lineNumber": 283,
"className": "com.ibm.ws.http.channel.inbound.impl.HttpInboundLink",
"nativeMethod": false
},
{
"methodName": "sendToDiscriminators",
"fileName": "NewConnectionInitialReadCallback.java",
"lineNumber": 214,
"className": "com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback",
"nativeMethod": false
},
{
"methodName": "complete",
"fileName": "NewConnectionInitialReadCallback.java",
"lineNumber": 113,
"className": "com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback",
"nativeMethod": false
},
{
"methodName": "futureCompleted",
"fileName": "AioReadCompletionListener.java",
"lineNumber": 165,
"className": "com.ibm.ws.tcp.channel.impl.AioReadCompletionListener",
"nativeMethod": false
},
{
"methodName": "invokeCallback",
"fileName": "AbstractAsyncFuture.java",
"lineNumber": 217,
"className": "com.ibm.io.async.AbstractAsyncFuture",
"nativeMethod": false
},
{
"methodName": "fireCompletionActions",
"fileName": "AsyncChannelFuture.java",
"lineNumber": 161,
"className": "com.ibm.io.async.AsyncChannelFuture",
"nativeMethod": false
},
{
"methodName": "completed",
"fileName": "AsyncFuture.java",
"lineNumber": 138,
"className": "com.ibm.io.async.AsyncFuture",
"nativeMethod": false
},
{
"methodName": "complete",
"fileName": "ResultHandler.java",
"lineNumber": 204,
"className": "com.ibm.io.async.ResultHandler",
"nativeMethod": false
},
{
"methodName": "runEventProcessingLoop",
"fileName": "ResultHandler.java",
"lineNumber": 775,
"className": "com.ibm.io.async.ResultHandler",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "ResultHandler.java",
"lineNumber": 905,
"className": "com.ibm.io.async.ResultHandler$2",
"nativeMethod": false
},
{
"methodName": "run",
"fileName": "ThreadPool.java",
"lineNumber": 1814,
"className": "com.ibm.ws.util.ThreadPool$Worker",
"nativeMethod": false
}
],
"additionalInformation": null,
"oauth2ErrorCode": "unauthorized",
"httpErrorCode": 401,
"summary": "error=\"unauthorized\", error_description=\"An Authentication object was not found in the SecurityContext\"",
"message": "An Authentication object was not found in the SecurityContext",
"localizedMessage": "An Authentication object was not found in the SecurityContext"
}
这是我的pom.xml:
<properties>
<spring.version>4.1.2.RELEASE</spring.version>
<jackson.version>1.9.13</jackson.version>
<javax.validation.version>1.1.0.Final</javax.validation.version>
<spring.security.version>3.2.5.RELEASE</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${javax.validation.version}</version>
</dependency>
<!-- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.1</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency> -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
4.1.2.1发布
1.9.13
1.1.0.1最终版本
3.2.5.1发布
javax.validation
验证api
${javax.validation.version}
org.springframework
弹簧芯
${spring.version}
org.springframework
弹簧网
${spring.version}
org.springframework
SpringWebMVC
${spring.version}
org.springframework
SpringJDBC
${spring.version}
com.fasterxml.jackson.core
杰克逊核心
2.4.1
com.fasterxml.jackson.core
杰克逊数据绑定
2.4.1.1
org.springframework
spring上下文支持
${spring.version}
org.springframework.security
spring安全网
${spring.security.version}
org.springframework.security
spring安全配置
${spring.security.version}
org.springframework.security.oauth
spring-security-oauth2
1.0.0.1版本
commons httpclient
commons httpclient
3.1
log4j
log4j
1.2.17
org.slf4j
slf4j-log4j12
1.6.1
javax.mail
邮件
1.5.0-b01
org.apache.commons
commons-lang3
3
这是我的spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"
/> -->
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<context:component-scan base-package="com.peoplcheck.*" />
<task:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/peoplecheck" />
</bean>
这是我的web.xml:
<servlet>
<servlet-name>people-check</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>people-check</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-servlet.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security -->
<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>
</filter-mapping>
人们检查
org.springframework.web.servlet.DispatcherServlet
1.
真的
人们检查
/
org.springframework.web.context.ContextLoaderListener
上下文配置位置
/WEB-INF/spring-servlet.xml,
/WEB-INF/spring-security.xml
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
这是我的spring-securiy.xml:
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<!-- This is simple authentication manager, with a hardcoded user/password
combination. We can replace this with a user defined service to get few users
credentials from DB -->
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider>
<user-service>
<user name="beingjavaguys" password="spring@java" authorities="ROLE_APP" />
</user-service>
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="420" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="restapp"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_APP" scope="read,write,trust" secret="secret" />
<oauth:client client-id="restapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="restapp" authorities="ROLE_APP" />
</oauth:client-details-service>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
您的一个依赖项可能会影响默认的Spring设置: 对于yml文件,更新为: 对于属性文件,更新为: 使用此设置重新启动后,
stackTrace
字段应消失。
我发现这个Spring引导提交似乎引入了以下设置:
spring:
error:
include-stacktrace: never
spring.error.include-stacktrace=never