Java 身份验证后如何显示用户特定的数据

Java 身份验证后如何显示用户特定的数据,java,microservices,Java,Microservices,我有两个微型服务。一个API网关,具有JWT身份验证和管理来自相应用户的模板的微服务。我的目标是用户只能看到他的模板。但我不清楚我是如何做到的。我是否必须生成一个额外的ID令牌,或者我还可以使用FIGN解决这个问题 @GetMapping("/templates/{name}/{template_id}") public Template retrieveTemplate(@PathVariable("name") String name,@PathVariable("template_

我有两个微型服务。一个API网关,具有JWT身份验证和管理来自相应用户的模板的微服务。我的目标是用户只能看到他的模板。但我不清楚我是如何做到的。我是否必须生成一个额外的ID令牌,或者我还可以使用FIGN解决这个问题

@GetMapping("/templates/{name}/{template_id}")
    public Template retrieveTemplate(@PathVariable("name") String name,@PathVariable("template_id") int template_id)
    {
        return templateRepository.findByTemplateIdAndName(template_id, name);

    }
这是我的get方法,可以显示相应的模板。但是,我不希望REST中需要用户名。在身份验证之后,应该可以使用令牌来输出特定于用户的数据,或者?我还有两个数据库表。一个用于身份验证,一个用于模板。在身份验证表中,我曾经有过数据用户名和密码以及用户名。在模板表中,我只有用户的名称(以保持表小)。这意味着,如果是来自模板的get请求,则必须从authentication microservice请求用户名,以便能够仅显示用户的模板。有人能告诉我哪种技术最适合我吗

@Service
public class JwtUtil {

        private String SECRET_KEY = "helloworld";

        public String extractUsername(String token)
        {
            return extractClaim(token, Claims::getSubject);
        }
        public Date extractExpiration(String token)
        {
            return extractClaim(token, Claims::getExpiration);
        }
        public <T> T extractClaim(String token, Function<Claims,T> claimsResolver)
        {
            final Claims claims = extractAllClaims(token);
            return claimsResolver.apply(claims);
        }
        private Claims extractAllClaims(String token)
        {
            return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
        }
        private Boolean isTokenExpired(String token)
        {
            return extractExpiration(token).before(new Date());
        }
        public String generateToken(UserDetails userDetails)
        {
            Map<String,Object> claims =new HashMap<>();
            return createToken(claims,userDetails.getUsername());
        }
        private String createToken(Map<String, Object> claims, String subject)
        {
            return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                    .setExpiration(new Date(System.currentTimeMillis() + 1000*60*60*24*360))
                    .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
        }
        public Boolean validateToken(String token, UserDetails userDetails)
        {
            final String username = extractUsername(token);
            return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
        }
}

package sendMessage.LoginJwtAPIGateway;
导入java.util.array;
导入java.util.Collection;
导入java.util.List;
导入java.util.Optional;
导入java.util.stream.collector;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.SimpleGrantedAuthority;
导入org.springframework.security.core.userdetails.userdetails;
公共类MyUserDetails实现UserDetails{
私有字符串用户名;
私有字符串密码;
私有布尔活动;
私人名单管理机构;
公共MyUserDetails()
{
}
公共MyUserDetails(用户){
this.username=user.getUsername();
this.password=user.getPassword();
this.active=user.isActive();
this.authorities=Arrays.stream(user.getRoles().split(“,”))
.map(SimpleGrantedAuthority::新建)
.collect(Collectors.toList());
}
@凌驾

公共集合如果您使用Spring和JWT生成令牌,那么您可以向JWT添加令牌增强器,令牌增强器允许您向令牌添加其他信息

然后,您可以将用户名或用户id添加到您的令牌中

在对模板端点的调用中,您可以删除url的名称部分。并依赖收到的令牌获取用户名


您可以在这里找到如何添加令牌增强器

如果您使用Spring和JWT生成令牌,那么您可以向JWT添加令牌增强器,令牌增强器允许您向令牌添加其他信息

然后,您可以将用户名或用户id添加到您的令牌中

在对模板端点的调用中,您可以删除url的名称部分。并依赖收到的令牌获取用户名


您可以在这里找到如何添加令牌增强器

您想要从他的JWT令牌中获取一些用户数据,因此您需要在生成用户令牌时向其添加一些额外信息,为此,您必须使用自定义的
令牌增强器

这篇文章可能对您的场景有用:

总之

  • 创建
    CustomTokenEnhancer

  • CustomTokenEnhancer
    作为bean添加到
    AuthorizationServerConfigurerAdapter

  • 从令牌获取保存的数据并使用它(在控制器中,…)


  • 您希望从他的JWT令牌中获取一些用户数据,因此在生成用户令牌时需要向其添加一些额外信息,为此,必须使用自定义的
    令牌增强器

    这篇文章可能对您的场景有用:

    总之

  • 创建
    CustomTokenEnhancer

  • CustomTokenEnhancer
    作为bean添加到
    AuthorizationServerConfigurerAdapter

  • 从令牌获取保存的数据并使用它(在控制器中,…)


  • 谢谢你的快速回答。我现在就测试它。谢谢你的快速回答。我现在就测试它。我对微服务和SpringBoot的世界还是很陌生。所以有时候我不确定我在做什么。:)我目前没有使用OAuth身份验证。但只有使用Spring Security和JWT。我可以重写增强器吗?我对这个世界还是很陌生的微服务和SpringBoot的世界。所以有时我不确定我在做什么。:)我目前没有使用OAuth身份验证。但只有使用Spring Security和JWT。我可以重写增强器吗?
    package sendMessage.LoginJwtAPIGateway;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.authentication.AuthenticationManager;
    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.config.http.SessionCreationPolicy;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    @EnableWebSecurity
    public class SecurityConfigurer extends WebSecurityConfigurerAdapter{
    
        @Autowired
        private MyUserDetailsService myUserDetailsService;
    
        @Autowired
        private JwtRequestFilter jwtRequestFilter;
    
        @Autowired
        UserDetailsService userDetailsService;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception
        {
            auth.userDetailsService(myUserDetailsService);
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                .authorizeRequests().antMatchers("/authenticate").permitAll().
                antMatchers("/users").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            http.addFilterBefore(jwtRequestFilter,  UsernamePasswordAuthenticationFilter.class);
        }
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception
        {
            return super.authenticationManagerBean();
        }
    
    
        @Bean
        public BCryptPasswordEncoder getBCryptPasswordEncoder()
        {
            return new BCryptPasswordEncoder();
        }
    
    }
    
    @Component
    public class JwtRequestFilter extends OncePerRequestFilter{
    
        @Autowired
        private MyUserDetailsService userDetailsService;
        @Autowired
        private JwtUtil jwtUtil;
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
                throws ServletException, IOException {
    
            final String authorizationHeader =request.getHeader("Authorization");
    
            String username = null;
            String jwt = null;
    
            if(authorizationHeader !=null && authorizationHeader.startsWith("Bearer "))
            {
                jwt = authorizationHeader.substring(7);
                username= jwtUtil.extractUsername(jwt);
            }
            if (username != null && SecurityContextHolder.getContext().getAuthentication()==null)
            {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
    
                if (jwtUtil.validateToken(jwt,  userDetails))
                {
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
                    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
            chain.doFilter(request,response);
        }
    
    }
    
    package sendMessage.LoginJwtAPIGateway;
    
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.List;
    import java.util.Optional;
    import java.util.stream.Collectors;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    public class MyUserDetails implements UserDetails{
    
        private String username;
        private String password;
        private boolean active;
        private List<GrantedAuthority> authorities;
    
    
        public MyUserDetails()
        {
    
        }
    
        public MyUserDetails(User user) {
            this.username=user.getUsername();
            this.password=user.getPassword();
            this.active=user.isActive();
            this.authorities =Arrays.stream(user.getRoles().split(","))
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList());
    
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            // TODO Auto-generated method stub
            return authorities;
        }
    
        @Override
        public String getPassword() {
            // TODO Auto-generated method stub
            return password;
        }
    
        public String getUsername() {
            // TODO Auto-generated method stub
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            // TODO Auto-generated method stub
            return active;
        }
    
    }