我正在尝试学习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”)时,该应用程序会生成令牌
但是,当我尝试将凭据发送到(“ http://127.0.0.1:8080/api/cliente/listar”)时,我每次都会收到403错误
任何帮助将不胜感激,我是Java的新秀,所以请多多包涵,谢谢。