Spring Security JWT响应403

时间:2019-03-06 18:39:58

标签: java spring-boot jwt

我正在尝试学习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的新秀,所以请多多包涵,谢谢。

0 个答案:

没有答案