【发布时间】:2017-05-09 01:36:31
【问题描述】:
我有 2 个过滤器
@WebFilter(urlPatterns = "/rest/*")
public class TokenFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filtering /rest/* requests");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("Matching /rest/* request");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Optional<String> userFromToken = getUserFromToken(request);
if (!userFromToken.isPresent()) {
response.sendError(HttpStatus.UNAUTHORIZED.value());
return;
}
System.out.println("filtered /rest request for " + userFromToken.get());
addAuthentication(response, userFromToken.get());
filterChain.doFilter(servletRequest, response);
}
@Override
public void destroy() {
}
}
和
@WebFilter(urlPatterns = "/login")
public class AppLoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filtering /login/ requests");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("Matching /login/ request");
HttpServletRequest request = (HttpServletRequest) servletRequest;
String idToken = ((HttpServletRequest) servletRequest).getHeader("X-ID-TOKEN");
HttpServletResponse response = (HttpServletResponse) servletResponse;
System.out.println("filtered /login request: " + idToken);
if (idToken != null) {
final Payload payload;
try {
payload = GoogleTokenVerifier.verify(idToken);
if (payload != null) {
// TODO: 5/6/17 get this username from DB (createOrGet)
final String username = "myUniqueUser";
AppTokenProviderAndAuthenticator.addAuthentication(response, username);
filterChain.doFilter(servletRequest, response);
return;
}
} catch (GeneralSecurityException | InvalidTokenException e) {
// This is not a valid token, we will send HTTP 401 back
}
}
((HttpServletResponse) servletResponse).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
@Override
public void destroy() {
}
}
和我的Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
当我启动我的应用程序时,我在日志中看到以下内容
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.3.RELEASE)
2017-05-09 13:28:40.841 INFO 80936 --- [ restartedMain] com.hhimanshu.secure.ServerApplication : Starting ServerApplication on HHimanshu-MBR64.local with PID 80936 (/Users/Harit.Himanshu/IdeaProjects/q2/server/target/classes started by Harit.Himanshu in /Users/Harit.Himanshu/IdeaProjects/q2/server)
2017-05-09 13:28:40.841 INFO 80936 --- [ restartedMain] com.hhimanshu.secure.ServerApplication : No active profile set, falling back to default profiles: default
2017-05-09 13:28:40.887 INFO 80936 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4e0339c5: startup date [Tue May 09 13:28:40 NZST 2017]; root of context hierarchy
2017-05-09 13:28:41.787 INFO 80936 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-05-09 13:28:41.793 INFO 80936 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-05-09 13:28:41.794 INFO 80936 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.14
2017-05-09 13:28:41.838 INFO 80936 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-05-09 13:28:41.838 INFO 80936 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 954 ms
2017-05-09 13:28:41.931 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-05-09 13:28:41.931 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-05-09 13:28:41.931 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-05-09 13:28:41.931 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-05-09 13:28:41.932 INFO 80936 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2017-05-09 13:28:41.932 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'com.hhimanshu.secure.auth.filters.AppLoginFilter' to urls: [/login]
2017-05-09 13:28:41.932 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'com.hhimanshu.secure.auth.filters.TokenFilter' to urls: [/rest/*]
2017-05-09 13:28:41.932 INFO 80936 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
filtering /login/ requests
filtering /rest/* requests
2017-05-09 13:28:42.089 INFO 80936 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4e0339c5: startup date [Tue May 09 13:28:40 NZST 2017]; root of context hierarchy
2017-05-09 13:28:42.120 INFO 80936 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/hello],methods=[GET]}" onto public java.lang.String com.hhimanshu.secure.api.HelloWorld.sayHello()
2017-05-09 13:28:42.120 INFO 80936 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login],methods=[POST]}" onto public void com.hhimanshu.secure.api.Login.authenticate()
2017-05-09 13:28:42.123 INFO 80936 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-05-09 13:28:42.123 INFO 80936 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-05-09 13:28:42.141 INFO 80936 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-09 13:28:42.142 INFO 80936 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-09 13:28:42.164 INFO 80936 --- [ restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-05-09 13:28:42.175 INFO 80936 --- [ restartedMain] oConfiguration$WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
2017-05-09 13:28:42.278 INFO 80936 --- [ restartedMain] b.a.s.AuthenticationManagerConfiguration :
Using default security password: d1915adb-5af3-48a2-b716-a87141be0fed
2017-05-09 13:28:42.305 INFO 80936 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
2017-05-09 13:28:42.349 INFO 80936 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1142b9af, org.springframework.security.web.context.SecurityContextPersistenceFilter@23f70e9, org.springframework.security.web.header.HeaderWriterFilter@476d93e7, org.springframework.security.web.authentication.logout.LogoutFilter@5e7064a4, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@605326d1, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4a058da6, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4b32f03e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3a8a09e6, org.springframework.security.web.session.SessionManagementFilter@6a816ad4, org.springframework.security.web.access.ExceptionTranslationFilter@2ab3c6b5, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@474d7d8f]
2017-05-09 13:28:42.389 INFO 80936 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2017-05-09 13:28:42.425 INFO 80936 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-05-09 13:28:42.464 INFO 80936 --- [ restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-05-09 13:28:42.468 INFO 80936 --- [ restartedMain] com.hhimanshu.secure.ServerApplication : Started ServerApplication in 1.779 seconds (JVM running for 2.088)
2017-05-09 13:28:47.546 INFO 80936 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-05-09 13:28:47.546 INFO 80936 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2017-05-09 13:28:47.556 INFO 80936 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 10 ms
但是,当我点击 URL 时,bean 已注册
curl -v -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJteVVuaXF1ZVVzZXIiLCJleHAiOjE0OTUwMDA3NjV9.B4Ax_BIkrW044rwVnN-qvLcT9r0JzP4VCECjExp3yTFqv4STNmEiG4LNBHU-BXjAOSgt9xuLV7LhVXPKLYApbQ" http://localhost:8080/rest/hello
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /rest/hello HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJteVVuaXF1ZVVzZXIiLCJleHAiOjE0OTUwMDA3NjV9.B4Ax_BIkrW044rwVnN-qvLcT9r0JzP4VCECjExp3yTFqv4STNmEiG4LNBHU-BXjAOSgt9xuLV7LhVXPKLYApbQ
>
< HTTP/1.1 401
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< WWW-Authenticate: Basic realm="Spring"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 09 May 2017 01:28:47 GMT
<
* Connection #0 to host localhost left intact
{"timestamp":1494293327580,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/rest/hello"}
它们不会被/rest/* 模式拦截,如TokenFilter 中所述。
另外,我的静态资源在身份验证后面被过滤(我不想要)
✗ curl -v http://localhost:8080/
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 401
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains
< WWW-Authenticate: Basic realm="Spring"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 09 May 2017 01:28:54 GMT
<
* Connection #0 to host localhost left intact
{"timestamp":1494293334189,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/"}% ➜ server git:(jwt) ✗
我在哪里做错了?
【问题讨论】:
标签: java spring spring-boot spring-security filter