【发布时间】:2022-08-16 02:23:28
【问题描述】:
我在一个基于 Spring Boot 和 Angular 的 Web 应用程序上工作。当用户登录客户端时,应用程序失败。我使用此链接https://github.com/bezkoder/angular-11-spring-boot-jwt-authentication 作为教程参考。我收到以下错误:
Client-> Failed to load resource: the server responded with a status of 401 ()
Server -> AuthEntryPointJwt : Unauthorized error: Full authentication is required to access this resource
AuthEntryPointJwt.java
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
logger.error(\"Unauthorized error: {}\", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, \"Error: Unauthorized\");
}
}
AuthTokenFilter.java
public class AuthTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
public static final String TOKEN_PREFIX = \"Bearer \";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
if (!username.isEmpty()) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
logger.error(\"Username is null\");
}
}else {
logger.error(\"jwt is null\");
}
} catch (Exception e) {
logger.error(\"Cannot set user authentication: {}\", e);
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader(AUTHORIZATION);
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith(TOKEN_PREFIX)) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}
JwtUtils.java
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value(\"${jwtSecret}\")
private String jwtSecret;
@Value(\"${jwtExpirationMs}\")
private String jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + Integer.valueOf(jwtExpirationMs)))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error(\"Invalid JWT signature: {}\", e.getMessage());
} catch (MalformedJwtException e) {
logger.error(\"Invalid JWT token: {}\", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error(\"JWT token is expired: {}\", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error(\"JWT token is unsupported: {}\", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error(\"JWT claims string is empty: {}\", e.getMessage());
}
return false;
}
}
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
public static final String[] AUTHENTICATED_URLS = { \"/app/user/**\", \"/app/item/**\"};
public static final String SIGN_UP_URL = \"/app/login\" ;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public AuthEntryPointJwt authenticationEntryPointJwt() {
return new AuthEntryPointJwt();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers(SIGN_UP_URL).permitAll()
.antMatchers(AUTHENTICATED_URLS ).permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
-
当 api 端点上未启用安全性时,我看到了此错误。您可以尝试将此属性添加到您的 application.properties:
management.security.enabled=false并查看是否可以解决错误。
标签: spring spring-boot spring-security jwt