nhu*_*uvy 9 java spring spring-security spring-boot
我的代码可以在 Spring 2.x 上正常工作。Spring 2.x的源代码
\n\n文件CustomFilter.java
package com.example.security;\n\nimport jakarta.servlet.FilterChain;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\nimport org.springframework.web.filter.GenericFilterBean;\n\nimport java.io.IOException;\n\npublic class CustomFilter extends GenericFilterBean {\n\n @Override\n public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {\n chain.doFilter(request, response);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n文件AuthEntryPointJwt.java
package com.example.security.jwt;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.MediaType;\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.web.AuthenticationEntryPoint;\nimport org.springframework.stereotype.Component;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\n@Component\npublic class AuthEntryPointJwt implements AuthenticationEntryPoint {\n\n private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);\n\n @Override\n public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {\n logger.error("Unauthorized error: {}", authException.getMessage());\n response.setContentType(MediaType.APPLICATION_JSON_VALUE);\n response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);\n final Map<String, Object> body = new HashMap<>();\n body.put("status", HttpServletResponse.SC_UNAUTHORIZED);\n body.put("error", "Unauthorized");\n body.put("message", authException.getMessage());\n body.put("path", request.getServletPath());\n final ObjectMapper mapper = new ObjectMapper();\n mapper.writeValue(response.getOutputStream(), body);\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n文件AuthTokenFilter.java
package com.example.security.jwt;\n\nimport com.example.security.services.UserDetailsServiceImpl;\nimport jakarta.servlet.FilterChain;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.web.authentication.WebAuthenticationDetailsSource;\nimport org.springframework.util.StringUtils;\nimport org.springframework.web.filter.OncePerRequestFilter;\n\nimport java.io.IOException;\n\npublic class AuthTokenFilter extends OncePerRequestFilter {\n\n private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);\n\n @Autowired\n private JwtUtils jwtUtils;\n\n @Autowired\n private UserDetailsServiceImpl userDetailsService;\n\n @Override\n protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {\n try {\n String jwt = parseJwt(request);\n if (jwt != null && jwtUtils.validateJwtToken(jwt)) {\n String username = jwtUtils.getUserNameFromJwtToken(jwt);\n UserDetails userDetails = userDetailsService.loadUserByUsername(username);\n UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());\n authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));\n SecurityContextHolder.getContext().setAuthentication(authentication);\n }\n } catch (Exception e) {\n logger.error("Cannot set user authentication: {}", e);\n }\n filterChain.doFilter(request, response);\n }\n\n private String parseJwt(HttpServletRequest request) {\n String headerAuth = request.getHeader("Authorization");\n if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {\n return headerAuth.substring(7);\n }\n return null;\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n文件JwtUtils.java
package com.example.security.jwt;\n\nimport com.example.security.services.UserDetailsImpl;\nimport io.jsonwebtoken.ExpiredJwtException;\nimport io.jsonwebtoken.Jwts;\nimport io.jsonwebtoken.MalformedJwtException;\nimport io.jsonwebtoken.SignatureAlgorithm;\nimport io.jsonwebtoken.SignatureException;\nimport io.jsonwebtoken.UnsupportedJwtException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Date;\n\n@Component\npublic class JwtUtils {\n\n private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);\n\n @Value("${app.jwtSecret}")\n private String jwtSecret;\n\n @Value("${app.jwtExpirationMs}")\n private int jwtExpirationMs;\n\n public String generateJwtToken(Authentication authentication) {\n UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();\n return Jwts.builder().setSubject((userPrincipal.getUsername())).setIssuedAt(new Date()).setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)).signWith(SignatureAlgorithm.HS512, jwtSecret).compact();\n }\n\n public String getUserNameFromJwtToken(String token) {\n return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();\n }\n\n public boolean validateJwtToken(String authToken) {\n try {\n Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);\n return true;\n } catch (SignatureException e) {\n logger.error("Invalid JWT signature: {}", e.getMessage());\n } catch (MalformedJwtException e) {\n logger.error("Invalid JWT token: {}", e.getMessage());\n } catch (ExpiredJwtException e) {\n logger.error("JWT token is expired: {}", e.getMessage());\n } catch (UnsupportedJwtException e) {\n logger.error("JWT token is unsupported: {}", e.getMessage());\n } catch (IllegalArgumentException e) {\n logger.error("JWT claims string is empty: {}", e.getMessage());\n }\n return false;\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n文件UserDetailsImpl.java
package com.example.security.services;\n\nimport com.example.models.User;\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport org.springframework.security.core.GrantedAuthority;\nimport org.springframework.security.core.authority.SimpleGrantedAuthority;\nimport org.springframework.security.core.userdetails.UserDetails;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.stream.Collectors;\n\npublic class UserDetailsImpl implements UserDetails {\n\n private static final long serialVersionUID = 1L;\n private Long id;\n private String username;\n private String email;\n\n @JsonIgnore\n private String password;\n\n private Collection<? extends GrantedAuthority> authorities;\n\n public UserDetailsImpl(Long id, String username, String email, String password, Collection<? extends GrantedAuthority> authorities) {\n this.id = id;\n this.username = username;\n this.email = email;\n this.password = password;\n this.authorities = authorities;\n }\n\n public static UserDetailsImpl build(User user) {\n List<GrantedAuthority> authorities = user.getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getName().name())).collect(Collectors.toList());\n return new UserDetailsImpl(user.getId(), user.getUsername(), user.getEmail(), user.getPassword(), authorities);\n }\n\n @Override\n public Collection<? extends GrantedAuthority> getAuthorities() {\n return authorities;\n }\n\n public Long getId() {\n return id;\n }\n\n public String getEmail() {\n return email;\n }\n\n @Override\n public String getPassword() {\n return password;\n }\n\n @Override\n public String getUsername() {\n return username;\n }\n\n @Override\n public boolean isAccountNonExpired() {\n return true;\n }\n\n @Override\n public boolean isAccountNonLocked() {\n return true;\n }\n\n @Override\n public boolean isCredentialsNonExpired() {\n return true;\n }\n\n @Override\n public boolean isEnabled() {\n return true;\n }\n\n @Override\n public boolean equals(Object o) {\n if (this == o)\n return true;\n if (o == null || getClass() != o.getClass())\n return false;\n UserDetailsImpl user = (UserDetailsImpl) o;\n return Objects.equals(id, user.id);\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n文件UserDetailsServiceImpl.java
package com.example.security.services;\n\nimport com.example.models.User;\nimport com.example.repository.UserRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\n// Original.\n@Service\npublic class UserDetailsServiceImpl implements UserDetailsService {\n\n @Autowired\n UserRepository userRepository;\n\n @Override\n @Transactional\n public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {\n User user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));\n return UserDetailsImpl.build(user);\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n文件WebSecurityConfig.java
package com.example.security;\n\nimport com.example.security.jwt.AuthEntryPointJwt;\nimport com.example.security.jwt.AuthTokenFilter;\nimport com.example.security.services.UserDetailsServiceImpl;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.security.authentication.AuthenticationManager;\nimport org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;\nimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\nimport org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\nimport org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\nimport org.springframework.security.config.http.SessionCreationPolicy;\nimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\nimport org.springframework.security.crypto.password.PasswordEncoder;\nimport org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;\n\n@Configuration\n@EnableWebSecurity\n@EnableGlobalMethodSecurity(\n // securedEnabled = true,\n // jsr250Enabled = true,\n prePostEnabled = true)\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n\n @Autowired\n UserDetailsServiceImpl userDetailsService;\n\n @Autowired\n private AuthEntryPointJwt unauthorizedHandler;\n\n @Bean\n public AuthTokenFilter authenticationJwtTokenFilter() {\n return new AuthTokenFilter();\n }\n\n @Override\n public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {\n authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());\n }\n\n @Bean\n @Override\n public AuthenticationManager authenticationManagerBean() throws Exception {\n return super.authenticationManagerBean();\n }\n\n @Bean\n public PasswordEncoder passwordEncoder() {\n return new BCryptPasswordEncoder();\n }\n\n\n // N\xe1\xba\xbfu id g\xe1\xbb\xadi l\xc3\xaan != id c\xe1\xbb\xa7a tenant c\xe1\xbb\xa7a user \xc4\x91\xc3\xb3 trong database, th\xc3\xac kh\xc3\xb4ng cho \xc4\x91i ti\xe1\xba\xbfp.\n @Override\n protected void configure(HttpSecurity http) throws Exception {\n http.cors().and().csrf().disable()\n .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()\n .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()\n //.authorizeRequests().antMatchers("/api/auth/**", "/swagger-ui/**").permitAll()\n\n .authorizeRequests().antMatchers("/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll()\n\n .antMatchers("/app/**").permitAll()\n .antMatchers("/api/test/**").permitAll()\n .anyRequest().authenticated();\n http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);\n //;\n\n // .addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); // VyDN 2022_07_22 // https://www.baeldung.com/spring-security-custom-filter\n }\n\n}\n\n// Add filter before, after: https://stackoverflow.com/a/59000469\n\nRun Code Online (Sandbox Code Playgroud)\n现在,我使用 Java / JDK 19,Spring Boot 3.0.0 。升级到 Spring Boot 3.0.0 后,导致语法错误。
如何修复WebSecurityConfigurerAdapter升级到 Spring Boot 3.0.0 时出现的错误?具体到我的配置。请指导我重写文件WebSecurityConfig.java
WebSecurityConfigurerAdapter 已弃用,应使用基于组件的安全配置。您必须为 HTTPSecurity 创建一个 SecurityFilterChain bean,并且不应按照其他答案的建议扩展WebSecurityConfigurerAdapter。请参阅https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter了解更多详细信息。
小智 1
在 Spring Boot 3 上WebSecurityConfigurerAdapter已弃用。因此,在您的情况下,该类WebSecurityConfig不应扩展任何类,并且大多数类应由其自身实现。您可以自己将 实现userDetailsService为 a@Bean并设置AuthenticationManager,而不仅仅是返回 super 。我遇到了同样的问题,我的解决方案只是在类中的注释@SuppressWarnings("deprecation")
之前添加。@Configuration
| 归档时间: |
|
| 查看次数: |
37280 次 |
| 最近记录: |