I am trying to secure my Spring Rest API with token here is my custom filter
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);
}
}
and here is how I configured it
@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();
}
}
If you look at the getFilter(), I have passed "/api/*" as a filter processing url, but I want to configure these urls with HttpSecurity object, some thing as follows
http.authorizeRequests().antMatchers("/", "/rome").permitAll()
.antMatchers("/api/admin", "/api/newUser").access("hasRole('ADMIN')")
.antMatchers("/api/db").access("hasRole('ADMIN') or hasRole('DBA')")
Problem I see is that, the Custom filter requires a String as "filter processing url" but I do not want specify anything. That information should be passed by configuring HttpSecurity
object through antMatchers
etc.
Is it really possible? if yes how can I achieve that?
I used 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
}
}
You can treat this class as a normal bean (use @Autowired
and so on). Then you just need do register it in your context and inject it in the security chain.
Hope it helps.
This answer will be useful to you. It says to use setter setFilterProcessingURL() available in AbstractAuthenticationProcessingFilter
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.