我们设法完全按照OP中的描述使其工作,并希望其他人可以使用该解决方案。 这是我们做的:
像这样设置安全上下文:
class="com.demo.api.support.spring.CustomAuthenticationEntryPoint" />
class="com.demo.api.support.spring.AuthenticationTokenProcessingFilter" >
正如您所看到的,我们创建了一个自定义TokenUtils,如果请求未在我们的AuthenticationTokenProcessingFilter过滤器链中进行身份验证,则基本上只返回401 Unauthorized。
CustomAuthenticationEntryPoint:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Authentication token was either missing or invalid." );
}
}
AuthenticationTokenProcessingFilter:
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
@Autowired UserService userService;
@Autowired TokenUtils tokenUtils;
AuthenticationManager authManager;
public AuthenticationTokenProcessingFilter(AuthenticationManager authManager) {
this.authManager = authManager;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
@SuppressWarnings("unchecked")
Map parms = request.getParameterMap();
if(parms.containsKey("token")) {
String token = parms.get("token")[0]; // grab the first "token" parameter
// validate the token
if (tokenUtils.validate(token)) {
// determine the user based on the (already validated) token
UserDetails userDetails = tokenUtils.getUserFromToken(token);
// build an Authentication object with the user's info
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
// set the authentication into the SecurityContext
SecurityContextHolder.getContext().setAuthentication(authManager.authenticate(authentication));
}
}
// continue thru the filter chain
chain.doFilter(request, response);
}
}
显然,TokenUtils包含一些私有(和特定于案例的)代码,不能轻易共享。 这是它的界面:
public interface TokenUtils {
String getToken(UserDetails userDetails);
String getToken(UserDetails userDetails, Long expiration);
boolean validate(String token);
UserDetails getUserFromToken(String token);
}
这应该让你有一个良好的开端。 快乐的编码。:)