Ответ Spring Security JWT 403 - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь изучить Java и Spring, я шаг за шагом следую учебному пособию по безопасности Spring, но получаю http-ответ, запрещенный, опять же, я новичок в Java, так что, если это глупо ошибка, поверь мне, я не вижу этого.

вот мой SpringSecurityConfig.java

package com.bolsadeideasspringboot.app;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.User.UserBuilder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.bolsadeideasspringboot.app.auth.filter.JWTAuthenticationFilter;
import com.bolsadeideasspringboot.app.auth.filter.JWTAuthorizationFilter;
import com.bolsadeideasspringboot.app.auth.handler.LoginSuccessHandler;
import com.bolsadeideasspringboot.app.models.service.JpaUserDetailService;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired
private LoginSuccessHandler successHandler;

@Autowired
private DataSource dataSource;

@Autowired
private BCryptPasswordEncoder passwordEncoder;

@Autowired
private JpaUserDetailService userDetailsService;

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

    http.authorizeRequests()
    .antMatchers("/", "/css/**", "/js/**", "/img/**", "/listar**").permitAll()
    .anyRequest().authenticated()
    .and()
    .addFilter(new JWTAuthenticationFilter(authenticationManager()))
    .addFilter(new JWTAuthorizationFilter(authenticationManager()))
    .csrf().disable()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Autowired
public void configurerglobal(AuthenticationManagerBuilder build) throws Exception {


    build.userDetailsService(userDetailsService)
    .passwordEncoder(passwordEncoder);

}

}

Вот мой JWTAuthenticationFilter.java

package com.bolsadeideasspringboot.app.auth.filter;

import java.io.Console;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.bolsadeideasspringboot.app.models.entity.Usuario;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private AuthenticationManager authManager;

public JWTAuthenticationFilter(AuthenticationManager authManager) {
    this.authManager = authManager;
    setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/login", "POST"));
    //setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/cliente/listar", "POST"));
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException {
    // TODO Auto-generated method stub


    String username = obtainUsername(request);
    String password = obtainPassword(request);

    if(username != null && password != null) {
        System.out.println("");
    }
    else {
        Usuario user = null;
        try {
            user = new ObjectMapper().readValue(request.getInputStream(), Usuario.class);
            username = user.getUsername();
            password = user.getPassword();

        } catch (JsonParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username,password);

    username = username.trim();

    return authManager.authenticate(authToken);
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
        Authentication authResult) throws IOException, ServletException {
    // TODO Auto-generated method stub

    Collection<? extends GrantedAuthority> roles = authResult.getAuthorities();
    Claims claims = Jwts.claims();
    claims.put("authorities", new ObjectMapper().writeValueAsString(roles));

    String token = Jwts.builder()
            .setClaims(claims)
            .setSubject(authResult.getName())
            .signWith(SignatureAlgorithm.HS512, "Clave!#$%&/()Secreta.//1234.4321.//.abcd.dcba.1a.2b.3c.4d.12345678".getBytes())
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 3600000L))
            .compact();

    response.addHeader("Authorization", "Bearer"+token);

    Map<String, Object> body = new HashMap<String, Object>();
    body.put("token", token);
    body.put("user", (User)authResult.getPrincipal());
    body.put("mensaje", "Inicio de sesión correcto");

    response.getWriter().write(new ObjectMapper().writeValueAsString(body));
    response.setStatus(200);
    response.setContentType("application/json");


    //super.successfulAuthentication(request, response, chain, authResult);
}

@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {
    // TODO Auto-generated method stub

    Map<String, Object> body = new HashMap<String, Object>();
    body.put("mensaje","Error de Autenticación, Claves de Acceso incorrectas");
    body.put("Error", failed.getMessage());

    response.getWriter().write(new ObjectMapper().writeValueAsString(body));
    response.setStatus(401);
    response.setContentType("application/json");

}
}

Вот JWTAuthorizationFilter.java

package com.bolsadeideasspringboot.app.auth.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import com.bolsadeideasspringboot.app.auth.SimpleGrantedAuthoritiesMixin;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
    super(authenticationManager);
    // TODO Auto-generated constructor stub
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    String header = request.getHeader("Authorization");

    if(!requiresAuthentication(header)) {
        chain.doFilter(request, response);
        return;
    }

    boolean tokenValid;
    Claims token = null;

    try {
        token = Jwts.parser()
        .setSigningKey("Clave!#$%&/()Secreta.//1234.4321.//.abcd.dcba.1a.2b.3c.4d.12345678".getBytes())
        .parseClaimsJws(header.replace("Bearer ", "")).getBody();
        tokenValid = true;
    }
    catch(JwtException e) {
        tokenValid = false;
    }

    UsernamePasswordAuthenticationToken authentication = null;

    if(tokenValid) {

        String username = token.getSubject();
        Object roles = token.get("authorities");

        Collection<? extends GrantedAuthority> authorities = Arrays.asList(new ObjectMapper()
                .addMixIn(SimpleGrantedAuthority.class, SimpleGrantedAuthoritiesMixin.class)
                .readValue(roles.toString().getBytes(), SimpleGrantedAuthority[].class));

        authentication = new UsernamePasswordAuthenticationToken(username, null, authorities);

    }

    SecurityContextHolder.getContext().setAuthentication(authentication);
    chain.doFilter(request, response);


}

protected boolean requiresAuthentication(String header) {
    if (header == null || !header.toLowerCase().startsWith("Bearer ")) {

        return false;
    }
    return true;
}   
}

Итак, в основном, когда я пытаюсь войти в систему по маршруту входа в систему ("http://127.0.0.1:8080/api/login"), работает, приложение генерирует токен

enter image description here

но, когда я пытаюсь отправить учетные данные в ("http://127.0.0.1:8080/api/cliente/listar"),, я получаю ошибку 403 каждый раз

enter image description here

Буду признателен за любую помощь, еще раз, я новичок в Java, поэтому, пожалуйста, потерпите меня, спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...