gpt4 book ai didi

java - Spring使用JWT身份验证,获取当前用户

转载 作者:行者123 更新时间:2023-12-02 02:05:56 25 4
gpt4 key购买 nike

我有 Spring Boot REST 应用程序,它使用 JWT token 进行授权。我想使用 @AuthenticationPrincipal 注释获取 Controller 中当前登录的用户。但如果我从 loadUserByUsername 返回自定义模型并且身份验证停止工作,它总是返回 null。我的模型实现了UserDetails

我尝试扩展org.springframework.security.core.userdetails.User,但我从JWTAuthenticationFilter中删除了默认构造函数不存在的错误(ApplicationUser creds = new ObjectMapper().readValue(req.getInputStream(), ApplicationUser.class);)

怎么了?

UserDetailsS​​erviceImpl.java

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private UserRepository userRepository;

public UserDetailsServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
ApplicationUser applicationUser = userRepository.findByUsername(username);
if (applicationUser == null) throw new UsernameNotFoundException(username);

return applicationUser;
}
}

ApplicationUser.java(模型)

@Entity
@Table(name = "users")
public class ApplicationUser implements UserDetails {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(unique = true, nullable = false)
private String username;

@Column(unique = true, nullable = false)
private String email;

@Column(nullable = false)
private String password;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public boolean isAccountNonExpired() {
return false;
}

@Override
public boolean isAccountNonLocked() {
return false;
}

@Override
public boolean isCredentialsNonExpired() {
return false;
}

@Override
public boolean isEnabled() {
return false;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
}

JWTAuthenticationFilter

public class JWTAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private AuthenticationManager authenticationManager;

public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher(LOGIN_URL));

this.authenticationManager = authenticationManager;
}

@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
ApplicationUser creds = new ObjectMapper()
.readValue(req.getInputStream(), ApplicationUser.class);

return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword(),
new ArrayList<>())
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {

String token = Jwts.builder()
.setSubject(((ApplicationUser) auth.getPrincipal()).getUsername())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET.getBytes())
.compact();

res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
}

JWTAuthorizationFilter

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}

@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);

if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}

UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}

private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user;
try {
user = Jwts.parser()
.setSigningKey(SECRET.getBytes())
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
} catch (SignatureException e) {
return null;
}

if (user != null) return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());

return null;
}
return null;
}
}

最佳答案

在您的情况下,@AuthenticationPrincipal 将返回带有用户名的字符串,您可以通过调用 Controller 中的存储库并通过用户名获取用户或将存储库声明为 @Bean 并执行以下操作来获取用户:

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

//Get the repository
private UserRepository userRepository;

public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}

@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);

if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}

UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}

private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user;
try {
user = Jwts.parser()
.setSigningKey(SECRET.getBytes())
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
} catch (SignatureException e) {
return null;
}

//Get your user
UserEntity userEntity = this.userRepository.findByUsername(user);

if (user != null) {
//Seting in your AuthenticationPrincipal the user
return new UsernamePasswordAuthenticationToken(userEntity, null, new ArrayList<>());
}

return null;
}
return null;
}

}

关于java - Spring使用JWT身份验证,获取当前用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50803727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com