我不知道我做错了什么。我试图实现Jwt令牌(仅post方法)。它显示了
路径为[]的上下文中servlet[dispatcherServlet]的servlet.Service()引发异常[请求处理失败;嵌套异常为java.lang.ClassCastException:类com.vivek.Discussion.Service.UserDetailServiceImpl$1不能强制转换为类com.vivek.Discussion.Model.User(com.vivek.Discussion.Service.UserDetailServiceImpl$1和com.vivek.Discussion.Service.UserDetailServiceImpl$1位于加载程序'app'的未命名模块中)],具有根本原因
java.lang.ClassCastException:类com.vivek.Discussion.Service.UserDetailServiceImpl$1不能强制转换为类com.vivek.Discussion.Service.Model.User(com.vivek.Discussion.Service.UserDetailServiceImpl$1和com.vivek.Discussion.Service.UserDiscussion.User位于com.vivek.Discussion.Security.jwtProvider.GenerateToken(jwtProvider.java:26)~[类/:na]位于
我不会分享DTO类。我知道问题出在Jwtprovider中,但不知道为什么
UserDetailService
package com.vivek.discussion.service;
@AllArgsConstructor
@Service
public class UserDetailServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username){
Optional<User> userOptional=userRepository.findByUsername(username);
User user=userOptional.orElseThrow(()-> new UsernameNotFoundException("User name not valid "+username));
return new UserDetails() {
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return UserDetailServiceImpl.this.getAuthorities("USER");
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return user.isEnabled();
}
};
}
private Collection<? extends GrantedAuthority> getAuthorities(String role) {
return Collections.singletonList(new SimpleGrantedAuthority(role));
}
}
authService
package com.vivek.discussion.service;
@Service
@AllArgsConstructor
public class AuthService {
// constructor injection is recommended over direct autowired annotation
private final PasswordEncoder passwordEncoder;
private final UserRepository userRepository;
private final VerificationTokenRepository verificationTokenRepository;
private final MailService mailService;
private final AuthenticationManager authenticationManager;
private final JwtProvider jwtProvider;
@Transactional
public void signup(RegisterRequest registerRequest){
User user=new User();
user.setUsername(registerRequest.getUsername());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
user.setEmail(registerRequest.getEmail());
user.setCreated(Instant.now());
user.setEnabled(false);
userRepository.save(user);
String token=generateRandomToken(user);
mailService.sendMail(new NotificationEmail("Please Activate Your Account",user.getEmail(),"thank you For Signing In Into our disscusion form" +
"Please click the link below to get : "+
"http://localhost:8080/api/auth/accountVerification/"+token));
}
private String generateRandomToken (User user){
String s= UUID.randomUUID().toString();
VerificationToken verificationToken=new VerificationToken();
verificationToken.setToken(s);
verificationToken.setUser(user);
verificationTokenRepository.save(verificationToken);
return s;
}
public void verifyAccount(String token) {
Optional<VerificationToken> verificationToken= verificationTokenRepository.findAllByToken(token);
verificationToken.orElseThrow(() -> new SpringDiscussionException("Invalid Token"));
fetchUserAndUnable(verificationToken.get());
}
@Transactional
void fetchUserAndUnable(VerificationToken verificationToken) {
String username=verificationToken.getUser().getUsername();
User user=userRepository.findByUsername(username).orElseThrow(()-> new SpringDiscussionException("User not found with name : "+username));
user.setEnabled(true);
userRepository.save(user);
}
public AuthenticationResponse login(LoginRequest loginRequest) {
Authentication authentication=authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(),loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String token= jwtProvider.generateToken(authentication);
return new AuthenticationResponse(token,loginRequest.getUsername());
}
}
AuthController
@Slf4j
@RestController
@RequestMapping("/api/auth")
@AllArgsConstructor
public class AuthController {
private final AuthService authService;
@PostMapping("/signup")
public ResponseEntity<String> signup(@RequestBody RegisterRequest registerRequest){
log.info(registerRequest.getEmail());
authService.signup(registerRequest);
return new ResponseEntity<>("user registration link send", HttpStatus.OK );
}
@GetMapping("accountVerification/{token}")
public ResponseEntity<String> verify(@PathVariable String token){
authService.verifyAccount(token);
return new ResponseEntity<>("User is register",HttpStatus.OK);
}
@PostMapping("/login")
public AuthenticationResponse login(@RequestBody LoginRequest loginRequest){
return authService.login(loginRequest);
}
}
JWTProvider
package com.vivek.discussion.security;
import com.vivek.discussion.model.User;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.security.Key;
@Service
public class JwtProvider {
private Key key;
@PostConstruct
public void init(){
key= Keys.secretKeyFor(SignatureAlgorithm.HS256);
}
public String generateToken(Authentication authentication){
User principal=(User) authentication.getPrincipal();
return Jwts.builder().setSubject(principal.getUsername())
.signWith(key)
.compact();
}
}
pom.xml(仅jwt依赖项)
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
<version>0.10.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
<version>0.10.5</version>
</dependency>
安全配置
package com.vivek.discussion.configuration;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
问题是UserDetailsService
实现返回的是UserDetails
类型:
@Override
public UserDetails loadUserByUsername(String username){
Optional<User> userOptional=userRepository.findByUsername(username);
User user=userOptional.orElseThrow(()-> new UsernameNotFoundException("User name not valid "+username));
return new UserDetails() {
...
但是jWTProvider
请求的是user
类型的内容:
User principal=(User) authentication.getPrincipal();
与其返回匿名内部类,不如考虑向user
添加复制构造函数,并使用扩展user
类并实现userDetails
的静态内部类:
private static class InternalUser extends User implements UserDetails {
public InternalUser(User user) {
super(user); // call the copy constructor
}
// ... all the implemented methods from your anonymous class
}
然后,可以在userDetailsServiceImpl
中执行:
@Override
public UserDetails loadUserByUsername(String username){
Optional<User> userOptional = userRepository.findByUsername(username);
User user = userOptional.orElseThrow(
() -> new UsernameNotFoundException("User not valid"));
return new InternalUser(user);
}
我的错误:- java.lang.ClassCastException:类*不能强制转换为类java.io.Serializable(*位于加载程序'app'的未命名模块中;java.io.Serializable位于加载程序'bootstrap'的模块java.base中) 表示包和类名。
我的错误:- java.lang.ClassCastException:类*不能强制转换为类java.io.Serializable(*位于加载程序'app'的未命名模块中;java.io.Serializable位于加载程序'bootstrap'的模块java.base中) 表示包和类名。
我注意到,当其他人遇到这个问题时,那是因为他们试图投射对象。我没有试图投。此外,我试图询问一个对象是否存在于使用Spring Boot存储库的数据表中。出现以下问题: 问题到底是什么? 模型: 存储库: 测试: 如果相关,服务类: 错误信息: Hibernate:选择skillgroup0_。id为id1_7_,skillgroup0_。名称为name2_7_,skillgroup0_。从skil
我试图从生成的源创建一个bean。 每次我尝试运行我的spring boot应用程序时,我都会得到以下错误: 原因:java.lang.ClassCastException:类org.apache.cxf.endpoint.clientImpl无法强制转换为类com.xignite.services.xigniteCurrenciesSOAP(org.apache.cxf.endpoint.cli
我有1个应用程序和2个模块 框架结构 但我不能在MyApp中使用MyModule的文件。IDE显示我“无法访问”错误,我想扩展一个MyModule类的类。而且它不是从MyModule创建类的,有人对此有想法吗?怎么了?
我目前在Java面临一个仿制药的问题。我需要返回一个已转换到子级的父级实例。 下面的示例显示了我正在尝试实现的目标。 此代码不运行,而是产生以下异常: 类com.generics.generictest$parent不能强制转换为类com.generics.generictest$childEntity(com.generics.generictest$parent和com.generics.ge