I know that securing REST API is widely commented topic but I'm not able to create a small prototype that meets my criteria (and I need to confirm that these criteria are realistic). There are so many options how to secure resources and how work with Spring security, I need to clarify if my needs are realistic.
My requirements
Current status
My REST API works very well, but now I need to secure it. When I was looking for a solution I created a javax.servlet.Filter
filter:
@Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; String accessToken = request.getHeader(AUTHORIZATION_TOKEN); Account account = accountDao.find(accessToken); if (account == null) { throw new UnauthorizedException(); } chain.doFilter(req, res); }
But this solution with javax.servlet.filters
doesn't work as I need because there is an issue with exception handling via @ControllerAdvice
with Spring servlet dispatcher
.
What I need
I would like to know if these criteria are realistic and get any help, how to start securing REST API with Spring Security. I read many tutorials (e.g. Spring Data REST + Spring Security) but all work in very basic configuration - users with their credentials are stored in memory in configuration and I need to work with DBMS and create own authenticator.
Please give me some ideas how to start.
Token based authentication - users will provide its credentials and get unique and time limited access token. I would like to manage token creation, checking validity, expiration in my own implementation.
Actually, use Filter for token Auth - best way in this case
Eventually, you can create CRUD via Spring Data for managing Token's properties like to expire, etc.
Here is my token filter: http://pastebin.com/13WWpLq2
And Token Service Implementation
http://pastebin.com/dUYM555E
Some REST resources will be public - no need to authenticate at all
It's not a problem, you can manage your resources via Spring security config like this: .antMatchers("/rest/blabla/**").permitAll()
Some resources will be accessible only for users with administrator rights,
Take a look at @Secured
annotation to class. Example:
@Controller @RequestMapping(value = "/adminservice") @Secured("ROLE_ADMIN") public class AdminServiceController {
The other resource will be accessible after authorization for all users.
Back to Spring Security configure, you can configure your url like this:
http .authorizeRequests() .antMatchers("/openforall/**").permitAll() .antMatchers("/alsoopen/**").permitAll() .anyRequest().authenticated()
I don't want to use Basic authentication
Yep, via token filter, your users will be authenticated.
Java code configuration (not XML)
Back to the words above, look at @EnableWebSecurity
. Your class will be:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {}
You have to override the configure method. Code below, just for example, how to configure matchers. It's from another project.
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/assets/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .usernameParameter("j_username") .passwordParameter("j_password") .loginPage("/login") .defaultSuccessUrl("/", true) .successHandler(customAuthenticationSuccessHandler) .permitAll() .and() .logout() .logoutUrl("/logout") .invalidateHttpSession(true) .logoutSuccessUrl("/") .deleteCookies("JSESSIONID") .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .and() .csrf(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With