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