java – 使用JWT auth的Spring,获取当前用户

weixin_38066102 2019-09-12 01:11:27
我有Spring Boot REST应用程序,它使用JWT令牌进行授权.我想使用@AuthenticationPrincipal注释在控制器中获取当前记录的用户.但是如果我从loadUserByUsername返回自定义模型并且auth停止工作,它总是返回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; } }
...全文
371 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38098251 2019-09-12
  • 打赏
  • 举报
回复
在您的情况下,@ AuthenticationPrincipal将返回一个包含用户名的字符串,您可以通过调用控制器中的存储库并通过用户名获取用户或将存储库声明为@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; } }

435

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧