2

I want ignore all urls with HttpMethod.GET, and the Urls with Post,Delete,Put need be authenticated. My urls are "/api/manga","/api/grupos","/api/autor","/genero","/api/pagina","/api/capitulo"

PermitAll dont work with JWTFilter, if a remove the filter, work fine.

How ignore or permit all urls with HttpMethod.GET ? Need create separate api to authenticate?

WebSecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/api/manga", "/api/grupos", "/api/autor", "/genero", "/api/pagina",
                        "/api/capitulo")
                .permitAll().anyRequest().fullyAuthenticated().and()
                .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class).httpBasic()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf()
                .disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/favicon.ico", "/", "/index.html", "/registrar", "/autenticar", "/app/**");
    }
}

JWTAuthenticationFilter

public class JWTAuthenticationFilter extends GenericFilterBean {

    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final String AUTHORITIES_KEY = "roles";

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res,final FilterChain filterChain)
            throws IOException, ServletException {      

        final HttpServletRequest request = (HttpServletRequest) req;       

        String authReader = request.getHeader(AUTHORIZATION_HEADER);
        if (authReader == null || !authReader.startsWith("Bearer ")) {
            ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "invalido autorization");

        } else {
            try {
                final String token = authReader.substring(7);
                final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                request.setAttribute("claims", claims);
                SecurityContextHolder.getContext().setAuthentication(getAuthentication(claims));
                filterChain.doFilter(req, res);
            } catch (SignatureException e) {
                ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "invalid token");
            }
        }
    }

    public Authentication getAuthentication(Claims claims) {
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        List<String> roles = (List<String>) claims.get(AUTHORITIES_KEY);
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }

        User principal = new User(claims.getSubject(), "", authorities);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToklen = new UsernamePasswordAuthenticationToken(
                principal, "", authorities);

        return usernamePasswordAuthenticationToklen;
    }
}

Controller

@RestController
@Transactional
@RequestMapping(value="/api")
public class AutorController {

    @Autowired
    private AutorRepository autorRepository;

    @Autowired
    private AutorService autorService;

    @RequestMapping(value = "/autor/{id}", method = RequestMethod.GET)
    public @ResponseBody ResponseEntity<Page<AutorEntity>> buscarMangaPorId(@PathVariable(value = "id") Long id,
            Integer page) {

        AutorEntity autor = autorRepository.findOne(id);

        if (autor == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        if (page == null) {
            page = 0;
        }

        if (page >= 1) {
            page--;
        }

        Pageable pageable = new PageRequest(page, 20);

        return new ResponseEntity<>(autorService.buscarMangaPorId(id, pageable), HttpStatus.OK);
    }

    @RequestMapping(value = "/autor/lista", method = RequestMethod.GET)
    public List<AutorEntity> listarAutores() {

        return autorService.listarTodos();
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping(value = "/autor", method = RequestMethod.POST)
    public ResponseEntity<AutorEntity> cadastrarAutor(@RequestBody AutorEntity autor) {

        if (autorRepository.findOneByNome(autor.getNome()) != null) {
            throw new RuntimeException("Nome Repetido");
        }

        return new ResponseEntity<>(autorService.cadastrar(autor), HttpStatus.OK);
    }

I do not now if I need to create different api to separate HttpMethod.

How resolve this?

Braian Silva
  • 1,986
  • 1
  • 15
  • 21
  • 1
    .antMatchers(HttpMethod.GET) is enough to permit all get methods, I have experienced the same issue with the combination of Method and URL in antMatchers. if you still want to permit specific URLs with Get method I would suggest this way https://stackoverflow.com/questions/52631648/spring-securitys-permitall-doesnt-work-for-certain-endpoints/52632200#52632200 – saif Oct 05 '18 at 06:44
  • `AnonymousAuthenticationFilter` allows access for permit all rules, which is staying after `UsernamePasswordAuthenticationFilter`. In this case of course your JWT filter will be triggered first. First of all i suggest you change log level for security to the DEBUG, and you can see the processing order and filters order for your requests. As approach of your problem you can use multiple HTTP security configuration, in first just permit all required resources and second another your security rules. – borino Oct 05 '18 at 06:48
  • @saifali I ignored HttpMethod.Get and it worked. `web.ignoring().antMatchers(HttpMethod.GET);` – Braian Silva Oct 05 '18 at 16:49

2 Answers2

1

The solution is to ignore HttpMethod.GET, so all urls with the get method will be ignored.

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
        .antMatchers(HttpMethod.GET)
        .antMatchers("/favicon.ico", "/", "/index.html", "/registrar",
                "/autenticar", "/app/**");
    }
Braian Silva
  • 1,986
  • 1
  • 15
  • 21
0

You can provide method type wise security like blow.

@Override
protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests().antMatchers(HttpMethod.GET).permitAll();
     http.authorizeRequests().antMatchers(HttpMethod.POST).denyAll();
     http.authorizeRequests().antMatchers(HttpMethod.DELETE,"/url").denyAll();
     http.authorizeRequests().antMatchers(HttpMethod.PATCH,"/url").denyAll();
     http.authorizeRequests().antMatchers(HttpMethod.PUT,"/url/*").denyAll();
}

I hope it helps you to achieve your goal.

Alien
  • 15,141
  • 6
  • 37
  • 57
  • Did not work, return the error 401 Unauthorized. I tried to ignore HttpMethot, GET and it worked very well. `web.ignoring().antMatchers (HttpMethod.GET);` – Braian Silva Oct 05 '18 at 16:50