我使用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);
}
}
我已經調試直到這點,並發現,在所有的情況下,我的安全上下文設置與正確的身份驗證和授權的用戶。
任何人都可以幫我理解問題的根源嗎?
在此先感謝。