Spring REST API 控制器在使用令牌进行身份验证时重定向到主页
Spring REST API Controller is redirecting to home when authenticated with token
我的 Spring 4 应用程序上有一个 API REST 控制器 returns JSON 值,但不知何故,查看日志,调度程序将请求重定向到“/”。
2016-04-01 11:30:35 DEBUG RequestResponseBodyMethodProcessor:221 - Written [{"type":"groupmatch"}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@4617ede3]
2016-04-01 11:30:35 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
2016-04-01 11:30:35 DEBUG ExceptionTranslationFilter:115 - Chain processed normally
2016-04-01 11:30:35 DEBUG SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing completed
2016-04-01 11:30:35 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/'
2016-04-01 11:30:35 DEBUG FilterChainProxy:180 - / has an empty filter list
2016-04-01 11:30:35 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing GET request for [/]
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:319 - Looking up handler method for path /
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:326 - Returning handler method [public java.lang.String com.thebetcafe.controllers.HomeController.home(org.springframework.web.context.request.WebRequest)]
2016-04-01 11:30:35 DEBUG DefaultListableBeanFactory:248 - Returning cached instance of singleton bean 'homeController'
2016-04-01 11:30:35 DEBUG DispatcherServlet:947 - Last-Modified value for [/] is: -1
2016-04-01 11:30:35 DEBUG DispatcherServlet:1241 - Rendering view [org.springframework.web.servlet.view.JstlView: name 'static/home.html'; URL [static/home.html]] in DispatcherServlet with name 'dispatcher'
2016-04-01 11:30:35 DEBUG JstlView:166 - Forwarding to resource [static/home.html] in InternalResourceView 'static/home.html'
2016-04-01 11:30:35 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing GET request for [/static/home.html]
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:319 - Looking up handler method for path /static/home.html
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:329 - Did not find handler method for [/static/home.html]
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:191 - Matching patterns for request [/static/home.html] are [/static/**]
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:220 - URI Template variables for request [/static/home.html] are {}
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:141 - Mapping [/static/home.html] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/static/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@6a23a6d6]]] and 1 interceptor
2016-04-01 11:30:35 DEBUG DispatcherServlet:947 - Last-Modified value for [/static/home.html] is: -1
2016-04-01 11:30:35 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
我有一个特定的过滤功能,可以通过 header 中的令牌对用户进行身份验证,但我不确定它是如何生成的。这是代码:
@RestController
@RequestMapping("/api")
public class APIController {
...
@RequestMapping(value="/groups",method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public @ResponseBody String getAllGroups(){
List<CompetitionGroup> groups = groupService.findAllGroups();
return groupListToJSONObject(groups);
}
...
}
dispatcher-servlet.xml
<!-- SCANNING THE COMPONENT -->
<context:component-scan base-package="com.myapp"/>
<context:annotation-config/>
<context:property-placeholder/>
<mvc:annotation-driven/>
<mvc:resources mapping="/static/**" location="/static/"/>
pom.xml
<!-- Jackson (JSON) -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
我在下面为 JWT 令牌身份验证实施了一个特定的过滤器:
public class JWTTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
private JWTUtil jwtUtil;
private static final Logger logger = Logger.getLogger(JWTTokenAuthenticationFilter.class);
public JWTTokenAuthenticationFilter(){
this("/api/");
}
public JWTTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
setAuthenticationManager(new NoOpAuthenticationManager());
setAuthenticationSuccessHandler(new JWTSuccessAuthenticationHandler());
}
public final String HEADER_SECURITY_TOKEN = "Authorization";
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return true;
}
/**
* Attempt to authenticate request - basically just pass over to another method to authenticate request headers
*/
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String header = request.getHeader(HEADER_SECURITY_TOKEN);
if (header == null || !header.startsWith("Bearer ")) {
throw new JwtTokenMissingException("No JWT token found in request headers");
}
/* Try to parse the token */
AppUser userDetails = jwtUtil.parseToken(header.substring(7));
Collection<SimpleGrantedAuthority> auth = new ArrayList<>();
auth.add(new SimpleGrantedAuthority(userDetails.getRole().name()));
JWTAuthenticationToken token = new JWTAuthenticationToken(userDetails.getEmail(), userDetails, auth);
token.setAuthenticated(true);
return token;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
// As this authentication is in HTTP header, after success we need to continue the request normally
// and return the response as if the resource was not secured at all
chain.doFilter(request, response);
}
}
诀窍是 AuthenticationSuccessHandler
在验证时将请求重定向到“/”。
所以我创建了一个新的JWTSuccessAuthenticationHandler
,他在身份验证后什么都不做。
public class JWTSuccessAuthenticationHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
// We do not need to do anything extra on REST authentication success, because there is no page to redirect to
}
}
希望对某人有所帮助:)
我的 Spring 4 应用程序上有一个 API REST 控制器 returns JSON 值,但不知何故,查看日志,调度程序将请求重定向到“/”。
2016-04-01 11:30:35 DEBUG RequestResponseBodyMethodProcessor:221 - Written [{"type":"groupmatch"}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@4617ede3]
2016-04-01 11:30:35 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
2016-04-01 11:30:35 DEBUG ExceptionTranslationFilter:115 - Chain processed normally
2016-04-01 11:30:35 DEBUG SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing completed
2016-04-01 11:30:35 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/'
2016-04-01 11:30:35 DEBUG FilterChainProxy:180 - / has an empty filter list
2016-04-01 11:30:35 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing GET request for [/]
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:319 - Looking up handler method for path /
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:326 - Returning handler method [public java.lang.String com.thebetcafe.controllers.HomeController.home(org.springframework.web.context.request.WebRequest)]
2016-04-01 11:30:35 DEBUG DefaultListableBeanFactory:248 - Returning cached instance of singleton bean 'homeController'
2016-04-01 11:30:35 DEBUG DispatcherServlet:947 - Last-Modified value for [/] is: -1
2016-04-01 11:30:35 DEBUG DispatcherServlet:1241 - Rendering view [org.springframework.web.servlet.view.JstlView: name 'static/home.html'; URL [static/home.html]] in DispatcherServlet with name 'dispatcher'
2016-04-01 11:30:35 DEBUG JstlView:166 - Forwarding to resource [static/home.html] in InternalResourceView 'static/home.html'
2016-04-01 11:30:35 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing GET request for [/static/home.html]
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:319 - Looking up handler method for path /static/home.html
2016-04-01 11:30:35 DEBUG RequestMappingHandlerMapping:329 - Did not find handler method for [/static/home.html]
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:191 - Matching patterns for request [/static/home.html] are [/static/**]
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:220 - URI Template variables for request [/static/home.html] are {}
2016-04-01 11:30:35 DEBUG SimpleUrlHandlerMapping:141 - Mapping [/static/home.html] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/static/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@6a23a6d6]]] and 1 interceptor
2016-04-01 11:30:35 DEBUG DispatcherServlet:947 - Last-Modified value for [/static/home.html] is: -1
2016-04-01 11:30:35 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
2016-04-01 11:30:35 DEBUG DispatcherServlet:1000 - Successfully completed request
我有一个特定的过滤功能,可以通过 header 中的令牌对用户进行身份验证,但我不确定它是如何生成的。这是代码:
@RestController
@RequestMapping("/api")
public class APIController {
...
@RequestMapping(value="/groups",method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public @ResponseBody String getAllGroups(){
List<CompetitionGroup> groups = groupService.findAllGroups();
return groupListToJSONObject(groups);
}
...
}
dispatcher-servlet.xml
<!-- SCANNING THE COMPONENT -->
<context:component-scan base-package="com.myapp"/>
<context:annotation-config/>
<context:property-placeholder/>
<mvc:annotation-driven/>
<mvc:resources mapping="/static/**" location="/static/"/>
pom.xml
<!-- Jackson (JSON) -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
我在下面为 JWT 令牌身份验证实施了一个特定的过滤器:
public class JWTTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
private JWTUtil jwtUtil;
private static final Logger logger = Logger.getLogger(JWTTokenAuthenticationFilter.class);
public JWTTokenAuthenticationFilter(){
this("/api/");
}
public JWTTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
setAuthenticationManager(new NoOpAuthenticationManager());
setAuthenticationSuccessHandler(new JWTSuccessAuthenticationHandler());
}
public final String HEADER_SECURITY_TOKEN = "Authorization";
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return true;
}
/**
* Attempt to authenticate request - basically just pass over to another method to authenticate request headers
*/
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String header = request.getHeader(HEADER_SECURITY_TOKEN);
if (header == null || !header.startsWith("Bearer ")) {
throw new JwtTokenMissingException("No JWT token found in request headers");
}
/* Try to parse the token */
AppUser userDetails = jwtUtil.parseToken(header.substring(7));
Collection<SimpleGrantedAuthority> auth = new ArrayList<>();
auth.add(new SimpleGrantedAuthority(userDetails.getRole().name()));
JWTAuthenticationToken token = new JWTAuthenticationToken(userDetails.getEmail(), userDetails, auth);
token.setAuthenticated(true);
return token;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
// As this authentication is in HTTP header, after success we need to continue the request normally
// and return the response as if the resource was not secured at all
chain.doFilter(request, response);
}
}
诀窍是 AuthenticationSuccessHandler
在验证时将请求重定向到“/”。
所以我创建了一个新的JWTSuccessAuthenticationHandler
,他在身份验证后什么都不做。
public class JWTSuccessAuthenticationHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
// We do not need to do anything extra on REST authentication success, because there is no page to redirect to
}
}
希望对某人有所帮助:)