文章目录
- 问题1
- 报错
- 解决
- 问题2
- 报错
- 解决
- 问题3
- 报错
- 解决
- 问题4
- 报错
- 解决
- 问题5
- 报错
- 解决
- 问题6
- 报错
- 解决
问题1
报错
You have entered a password with no PasswordEncoder. If that is your intent, it should be prefixed with {noop}
.
解决
Spring Security 期望密码使用 PasswordEncoder 进行编码。如果你想使用明文密码(不推荐在生产环境中使用),你需要用 {noop} 前缀来标识。
- 在Spring Security配置中,确保你有一个PasswordEncoder bean。Spring Security 5推荐使用BCryptPasswordEncoder,因为它提供了较强的安全性。
@Bean
public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder();
}
- 使用PasswordEncoder来加密密码。例如,如果你有一个用户服务,可以在创建或更新用户时加密密码。
@Autowired
private PasswordEncoder passwordEncoder; public void createUser(String username, String rawPassword) { String encodedPassword = passwordEncoder.encode(rawPassword); // 存储encodedPassword到数据库
}
问题2
报错
我在客户端调用自定义的路由 /login,提示302,服务端报错
o.s.s.c.bcrypt.BCryptPasswordEncoder : Empty encoded password
解决
其实是因为接口和Spring Security默认的接口冲突了,如/login、/logout
- 修改默认登录接口
你可以通过配置Spring Security的HttpSecurity来修改默认的登录接口路径。例如,将默认的登录路径改为 /auth/login:
import org.springframework.context.annotation.Configuration;
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;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/api/public/**").permitAll() // 公开接口.anyRequest().authenticated().and().formLogin().loginProcessingUrl("/auth/login") // 修改登录路径.permitAll(); // 允许所有用户访问}
}
- 使用不同的URL
确保你的自定义接口使用不同的URL。例如,如果你的自定义接口是 /api/login,则可以避免与Spring Security默认接口冲突。
问题3
报错
数据库连接报错Public Key Retrieval is not allowed
解决
方案一:修改 JDBC URL
在 JDBC URL 中添加 allowPublicKeyRetrieval=true
参数。这将允许客户端从服务器检索公钥:
jdbc:mysql://localhost:3306/yourDatabase?allowPublicKeyRetrieval=true&useSSL=false
方案二:检查 MySQL 用户权限
确保你使用的 MySQL 用户有权限执行公钥检索。可以通过在 MySQL 中执行以下命令来修改用户权限:
GRANT ALL PRIVILEGES ON yourDatabase.* TO 'yourUser'@'localhost';
FLUSH PRIVILEGES;
方案三:检查 MySQL 配置
在 MySQL 的配置文件(通常是 my.cnf 或 my.ini)中,检查是否有以下配置项:
[mysqld]
caching_sha2_password_auto_generate_rsa_keys=ON
问题4
报错
java17版本执行以下代码报错 java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
解决
jwt版本升级到最新0.12.6,但是一些 API 会变换
在版本 0.12.6 中,你需要使用 Jwts.parserBuilder() 来构建 JwtParser,然后再调用 parseClaimsJws。下面是一个示例:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.JwtParser;public class JwtExample {public static void main(String[] args) {String secret = "your_secret_key"; // 请使用更复杂的密钥String token = "your_jwt_token"; // 请替换为你生成的token// 解析 JWTClaims claims = Jwts.parserBuilder().setSigningKey(secret).build().parseClaimsJws(token).getBody();System.out.println("Parsed Claims: " + claims);}
}
关键变化
Jwts.parserBuilder():
- 现在使用 Jwts.parserBuilder() 创建一个 JwtParserBuilder 实例。
build()
方法:
- 在设置完签名密钥后,使用 build() 方法来创建 JwtParser 实例。
parseClaimsJws:
- 使用构建的 JwtParser 实例调用 parseClaimsJws(token) 方法来解析 JWT。
问题5
报错
io.jsonwebtoken.security.WeakKeyException: The signing key’s size is 152 bits which is not secure enough for the HS512 algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS512 MUST have a size >= 512 bits (the key size must be greater than or equal to the hash output size). Consider using the io.jsonwebtoken.security.Keys class’s ‘secretKeyFor(SignatureAlgorithm.HS512)’ method to create a key guaranteed to be secure enough for HS512. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.
解决
io.jsonwebtoken.security.WeakKeyException 错误表明你使用的签名密钥不够强大,具体来说,HS512 算法要求密钥至少为 512 位。要解决这个问题,你可以使用 io.jsonwebtoken.security.Keys 类中的 secretKeyFor 方法来生成一个安全的密钥。
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;import javax.crypto.SecretKey;public class JwtExample {public static void main(String[] args) {// 使用 Keys 类生成一个安全的密钥SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS512);// 生成 JWTClaims claims = Jwts.claims().setSubject("user");String token = Jwts.builder().setClaims(claims).signWith(secretKey).compact();System.out.println("Generated Token: " + token);// 解析 JWTClaims parsedClaims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token).getBody();System.out.println("Parsed Claims: " + parsedClaims);}
}
问题6
报错
class java.lang.String cannot be cast to class com.xxx.domain.model.LoginUser (java.lang.String is in module java.base of loader ‘bootstrap’; com.xxx.domain.model.LoginUser is in unnamed module of loader ‘app’)
解决
这个错误的意思是,你在代码中尝试将一个 String 类型的对象转换成 LoginUser 类型的对象
真实原因是SecurityContextHolder.getContext().getAuthentication().getPrincipal()结果是anonymousUser,anonymousUser 是 Spring Security 默认使用的一个特殊标识,表示未认证的用户。