我使用Spring Boot(版本:1.3.2)以及spring web和security。Spring Security:SecurityContextHolder在生产中没有填充正确的用户数据
场景:我有一个外部认证服务,它向尝试访问我的spring应用程序的API的客户端发出OAuth2令牌。为了截取和理解令牌,我遵循了this教程中提到的配置。这是一个基于Spring的无状态REST Api JWT令牌基于身份验证。
问题:当我在本地主机上运行我的应用并尝试从不同浏览器(隐身模式)访问应用时,事情正在为我工作。当我将它部署到我的Ubuntu 12.04服务器时出现问题。每当我尝试访问标记为@PreAuthorize(“hasAnyRole('ADMIN')”)的方法时,虽然用户已登录并被授权使用该API,但我正在获取401。
工作情况记录从本地主机:
2016-04-17 10:13:55 - Bound request context to thread: [email protected]
2016-04-17 10:13:55 - Trying to match using Ant [pattern='/css/**']
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/css/**'
2016-04-17 10:13:55 - Trying to match using Ant [pattern='/js/**']
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/js/**'
2016-04-17 10:13:55 - Trying to match using Ant [pattern='/images/**']
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/images/**'
2016-04-17 10:13:55 - Trying to match using Ant [pattern='/**/favicon.ico']
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/**/favicon.ico'
2016-04-17 10:13:55 - Trying to match using Ant [pattern='/error']
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/error'
2016-04-17 10:13:55 - No matches found
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 1 of 7 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-04-17 10:13:55 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.se[email protected]54d08125
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 2 of 7 in additional filter chain; firing Filter: 'StatelessAuthenticationFilter'
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 3 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 4 of 7 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-04-17 10:13:55 - SecurityContextHolder not populated with anonymous token, as it already contained: '[email protected]'
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 5 of 7 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-04-17 10:13:55 - Delegating to org.springframework.security.w[email protected]1d3565e1
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-04-17 10:13:55 - /api/purchaseOrders/get at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/'
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/resources/**'
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/app/login/**'
2016-04-17 10:13:55 - Checking match of request : '/api/purchaseorders/get'; against '/api/**'
2016-04-17 10:13:55 - Secure object: FilterInvocation: URL: /api/purchaseOrders/get; Attributes: [fullyAuthenticated]
2016-04-17 10:13:55 - Previously Authenticated: [email protected]
2016-04-17 10:13:55 - Voter: org.sp[email protected]446e8d44, returned: 1
2016-04-17 10:13:55 - Authorization successful
2016-04-17 10:13:55 - RunAsManager did not change Authentication object
2016-04-17 10:13:55 - /api/purchaseOrders/get reached end of additional filter chain; proceeding with original chain
2016-04-17 10:13:55 - DispatcherServlet with name 'dispatcherServlet' processing GET request for [/api/purchaseOrders/get]
2016-04-17 10:13:55 - Looking up handler method for path /api/purchaseOrders/get
2016-04-17 10:13:55 - Did not find handler method for [/api/purchaseOrders/get]
2016-04-17 10:13:55 - Looking up handler method for path /api/purchaseOrders/get
2016-04-17 10:13:55 - Returning handler method [public org.springframework.http.ResponseEntity<java.util.List<com.mycompany.inventory.dto.PurchaseOrderDTO>> com.mycompany.inventory.rest.controllers.PurchaseOrderApiController.getAllPurchaseOrders()]
2016-04-17 10:13:55 - Returning cached instance of singleton bean 'purchaseOrderApiController'
2016-04-17 10:13:55 - Last-Modified value for [/api/purchaseOrders/get] is: -1
2016-04-17 10:13:55 - Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2016-04-17 10:13:55 - Secure object: ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity com.mycompany.inventory.rest.controllers.PurchaseOrderApiController.getAllPurchaseOrders(); target is of class [com.mycompany.inventory.rest.controllers.PurchaseOrderApiController]; Attributes: [[authorize: 'hasAnyRole('ADMIN')', filter: 'null', filterTarget: 'null']]
2016-04-17 10:13:55 - Previously Authenticated: [email protected]
2016-04-17 10:13:55 - Voter: org.springframewor[email protected]6bb04370, returned: 1
2016-04-17 10:13:55 - Authorization successful
2016-04-17 10:13:55 - RunAsManager did not change Authentication object
2016-04-17 10:13:55 - Found thread-bound EntityManager [[email protected]] for JPA transaction
2016-04-17 10:13:55 - Creating new transaction with name [com.mycompany.inventory.servicesImpl.PurchaseOrderServiceImpl.getPurchaseOrders]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2016-04-17 10:13:55 - Exposing JPA transaction as JDBC transaction [org.springframewo[email protected]3400e582]
2016-04-17 10:13:55 - Found thread-bound EntityManager [[email protected]] for JPA transaction
2016-04-17 10:13:55 - Participating in existing transaction
2016-04-17 10:13:55 - Found thread-bound EntityManager [[email protected]] for JPA transaction
2016-04-17 10:13:55 - Participating in existing transaction
2016-04-17 10:13:55 - Initiating transaction commit
2016-04-17 10:13:55 - Committing JPA transaction on EntityManager [[email protected]]
2016-04-17 10:13:55 - Not closing pre-bound JPA EntityManager after transaction
2016-04-17 10:13:55 - Written [[]] as "application/json;charset=UTF-8" using [org.springfr[email protected]76cde05c]
2016-04-17 10:13:55 - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-04-17 10:13:55 - Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2016-04-17 10:13:55 - Closing JPA EntityManager
2016-04-17 10:13:55 - Successfully completed request
2016-04-17 10:13:55 - Chain processed normally
2016-04-17 10:13:55 - Cleared thread-bound request context: [email protected]
正如你可以看到: SecurityContextHolder中不填充匿名的原因,因为它已经包含:'[email protected] '
工作案例中的安全上下文报告已存在用户认证。即使这有效,我想知道这是否是正确的行为?由于我的配置是针对无状态会话的,因此安全上下文为什么要在其上下文中查找现有的身份验证条目?这是预期的吗?
不能工作的情况,从登录服务器:
2016-04-17 04:40:19 - Bound request context to thread: [email protected]
2016-04-17 04:40:19 - Trying to match using Ant [pattern='/css/**']
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/css/**'
2016-04-17 04:40:19 - Trying to match using Ant [pattern='/js/**']
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/js/**'
2016-04-17 04:40:19 - Trying to match using Ant [pattern='/images/**']
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/images/**'
2016-04-17 04:40:19 - Trying to match using Ant [pattern='/**/favicon.ico']
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/**/favicon.ico'
2016-04-17 04:40:19 - Trying to match using Ant [pattern='/error']
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/error'
2016-04-17 04:40:19 - No matches found
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 1 of 7 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-04-17 04:40:19 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.se[email protected]4a77b460
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 2 of 7 in additional filter chain; firing Filter: 'StatelessAuthenticationFilter'
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 3 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 4 of 7 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-04-17 04:40:19 - Populated SecurityContextHolder with anonymous token: 'org.sprin[email protected]905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]0: RemoteIpAddress: 122.171.94.145; SessionId: 4094950BB43FBE280B81842F649BA18E; Granted Authorities: ROLE_ANONYMOUS'
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 5 of 7 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-04-17 04:40:19 - /api/purchaseOrders/get at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/'
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/resources/**'
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/app/login/**'
2016-04-17 04:40:19 - Checking match of request : '/api/purchaseorders/get'; against '/api/**'
2016-04-17 04:40:19 - Secure object: FilterInvocation: URL: /api/purchaseOrders/get; Attributes: [fullyAuthenticated]
2016-04-17 04:40:19 - Previously Authenticated: org.sprin[email protected]905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]0: RemoteIpAddress: 122.171.94.145; SessionId: 4094950BB43FBE280B81842F649BA18E; Granted Authorities: ROLE_ANONYMOUS
2016-04-17 04:40:19 - Voter: org.sp[email protected]385462f, returned: -1
2016-04-17 04:40:19 - AuditEvent [timestamp=Sun Apr 17 04:40:19 UTC 2016, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]
2016-04-17 04:40:19 - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) ~[spring-security-core-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232) ~[spring-security-core-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123) ~[spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) ~[spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at com.drivojoy.inventory.helpers.StatelessAuthenticationFilter.doFilter(StatelessAuthenticationFilter.java:30) [classes!/:na]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) [spring-security-web-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar!/:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar!/:8.0.30]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar!/:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar!/:8.0.30]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
正如你所看到的:匿名令牌人口较少SecurityContextHolder的:“org.sprin[email protected]905571d8:负责人:anonymousUser;证书:[PROTECTED];已验证:true;详细信息:org.sprin[email protected]0:RemoteIpAddress:122.171.94.145; SessionId:4094950BB43FBE280B81842F649BA18E;授予的权限:ROLE_ANONYMOUS”
弹簧安全上下文加载在它的上下文匿名用户。以下是我的过滤器。
public class StatelessAuthenticationFilter extends GenericFilterBean {
private final TokenAuthenticationService authenticationService;
public StatelessAuthenticationFilter(TokenAuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
Authentication authentication = authenticationService.getAuthentication(httpRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
SecurityContextHolder.getContext().setAuthentication(null);
}
}
我已经调试直到这点,并发现,在所有的情况下,我的安全上下文设置与正确的身份验证和授权的用户。
任何人都可以帮我理解问题的根源吗?
在此先感谢。