我正在尝试使用令牌来保护我的Spring Rest API,这是我的自定义过滤器
public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationFilter.class);
public CustomTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
setAuthenticationManager(new NoOpAuthenticationManager());
setAuthenticationSuccessHandler(new TokenSimpleUrlAuthenticationSuccessHandler());
}
public final String HEADER_SECURITY_TOKEN = "X-CustomToken";
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String token = request.getHeader(HEADER_SECURITY_TOKEN);
logger.info("token found:"+token);
AbstractAuthenticationToken userAuthenticationToken = authUserByToken(token);
if(userAuthenticationToken == null || userAuthenticationToken.getPrincipal().equals("guest")) throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
return userAuthenticationToken;
}
/**
* authenticate the user based on token
* @return
*/
private AbstractAuthenticationToken authUserByToken(String token) {
if(token==null) {
return null;
}
AbstractAuthenticationToken authToken = new MyToken(token);
try {
return authToken;
} catch (Exception e) {
logger.error("Authenticate user by token error: ", e);
}
return authToken;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
super.doFilter(req, res, chain);
}
}
以下是我如何配置它
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
protected AbstractAuthenticationProcessingFilter getFilter() {
return new CustomTokenAuthenticationFilter("/api/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(getFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf().disable();
}
}
如果你看一下getFilter(),我已经通过" / api / *"作为过滤处理url,但我想用HttpSecurity对象配置这些url,有些东西如下
http.authorizeRequests().antMatchers("/", "/rome").permitAll()
.antMatchers("/api/admin", "/api/newUser").access("hasRole('ADMIN')")
.antMatchers("/api/db").access("hasRole('ADMIN') or hasRole('DBA')")
问题我看到,自定义过滤器需要一个字符串作为"过滤处理网址"但我不想指定任何东西。应通过HttpSecurity
等配置antMatchers
对象来传递该信息。
真的有可能吗?如果是的话我该如何实现?
答案 0 :(得分:0)
我使用了OncePerRequestFilter
。
public class MyAuthenticationFilter extends OncePerRequestFilter {
// private RequestMatcher requestMatcher;
private List<RequestMatcher> includedPathMatchers = new ArrayList<>();
private List<RequestMatcher> excludedPathMatchers = new ArrayList<>();
// implement getters and setters
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// your filter implementation and security logics
}
}
您可以将此类视为普通bean(使用@Autowired
等)。然后你只需要在你的上下文中注册它并将它注入安全链。
希望它有所帮助。
答案 1 :(得分:0)
此answer对您有用。它说要使用AbstractAuthenticationProcessingFilter中可用的setter setFilterProcessingURL()