java 如何从JWT获取用户名?

1hdlvixo  于 2022-12-17  发布在  Java
关注(0)|答案(5)|浏览(241)

我有两个微服务。一个是API网关,另一个是向客户发送消息的微服务。我的API在身份验证后返回一个JWT令牌。用户的用户名包含在令牌中。

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));
        }

如果我想通过API网关寻址我的SendMessage微服务,他需要用户名来发送消息。我目前通过Rest-Api传递用户名。我希望SendMessage微服务从令牌中获取用户名。我读到过这与TokenEnhancer一起工作。但我没有找到进一步的信息。有人能告诉我如何才能做到这一点,或者在哪里可以找到更多信息吗?

更新

@GetMapping("/contacts/sms/{name}/{customer_phone_number}/{text}")
            public String sendSmsToCustomer(@PathVariable("name") String name,@PathVariable("customer_phone_number") String customer_phone_number, @PathVariable("text") String text) throws Exception
            {
            
String user= getUsernameFromToken(HttpServletRequest request);
            
            
            SmsSubmissionResponse responses = client.getSmsClient().submitMessage(new TextMessage(
                    name,
                    customer_phone_number,
                    text));
            for (SmsSubmissionResponseMessage response : responses.getMessages()) {
                System.out.println (response);
            }
        
            if (responses.getMessages().get(0).getStatus() == MessageStatus.OK) {
                String date=new SimpleDateFormat("yyyy.MM.dd - HH:mm:ss").format(new java.util.Date());
                    SQL_Connection.SaveDataInSmsDB(name, customer_phone_number, text,date);
                    return "Message sent successfully.";
                } else {
                    return "Message failed with error: " + responses.getMessages().get(0).getErrorText();
                }
            }

更新2

一个二个一个一个

sg2wtvxw

sg2wtvxw1#

您可以使用以下代码从令牌中提取用户

String token = request.getHeader(HEADER_STRING);
    String user = null;
    if (token != null) {
        // parse the token.

        try {
            user = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                    .getBody()
                    .getSubject();

        } catch (Exception e) {

            throw e;

        }

你可以参考完整的代码和项目
https://github.com/techiesantosh/taskmanager-service/blob/develop/src/main/java/com/web/taskmanager/auth/TokenAuthenticationService.java

h43kikqp

h43kikqp2#

使用以下命令从jwt标记解析用户名

final String authHeader = request.getHeader("Authorization");
    String username = null;
    String jwt = null;

    if (authHeader != null && authHeader.startsWith("Bearer")) {
        jwt = authHeader.substring(7);
        username = jwtUtil.extractUsername(jwt);
    }
niknxzdl

niknxzdl3#

通过authentication.getName & principal.getName您可以获得用户名:

尝试以下代码:

@Controller
@RequestMapping("/info")
public class GetNameController {

    @RequestMapping(value = "/name", method = RequestMethod.GET)
    public String getName(Authentication authentication, Principal principal) {
        System.out.println(authentication.getName());
        System.out.println(principal.getName());
        return "";
    }
}
sczxawaw

sczxawaw4#

验证后,您可以通过覆盖successfulAuthentication()方法发送JWT令牌

生成令牌代码:

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
        Authentication authResult) throws IOException, ServletException {
    String userName = ((User)authResult.getPrincipal()).getUsername();
    UserDto userDetails = userService.getUserDetailsByEmail(userName);
    
    // Generate JWO Token
    String token = Jwts.builder()
            .setSubject(userDetails.getUserId())
            .setExpiration(new Date(System.currentTimeMillis() + Long.parseLong(env.getProperty("token.expiration_time"))))
            .signWith(SignatureAlgorithm.HS512, env.getProperty("token.secret"))
            .compact();
    response.addHeader("token", token);
    response.addHeader("userId", userDetails.getUserId());
}

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Autowired
    private Environment env;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        http.csrf().disable();
        http.headers().frameOptions().disable();
        http.authorizeRequests()
        .antMatchers(env.getProperty("api.h2console.url.path")).permitAll()
        .antMatchers(HttpMethod.POST, env.getProperty("api.registration.url.path")).permitAll()
        .antMatchers(HttpMethod.POST, env.getProperty("api.login.url.path")).permitAll()
        .anyRequest().authenticated();
        
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }   
}

获取请求后,将使用http.anyRequest().authenticated()方法进行身份验证,然后调用下面的授权过滤器对请求进行身份验证。
AuthorizationFilter.java

public class AuthorizationFilter extends BasicAuthenticationFilter{

    Environment environment;
    
    public AuthorizationFilter(AuthenticationManager authenticationManager, Environment environment) {
        super(authenticationManager);
        this.environment = environment;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req,HttpServletResponse res, FilterChain filter)
        throws IOException, ServletException{
        
        String authorizationHeader = req.getHeader(environment.getProperty("authorization.token.header.name"));
        
        if(authorizationHeader != null || 
                !authorizationHeader.startsWith(environment.getProperty("authorization.token.header.name.prefix"))) {
            filter.doFilter(req, res);
            
            return;
        }
        
        UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
        
        SecurityContextHolder.getContext().getAuthentication();
        filter.doFilter(req, res);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) {
            String authorizationHeader = req.getHeader(environment.getProperty("authorization.token.header.name"));
            
            if(authorizationHeader == null) {
                return null;
            }
            
            String token = authorizationHeader.replace(
                    environment.getProperty("authorization.token.header.name.prefix"), "");
            String userId = Jwts.parser()
                    .setSigningKey(environment.getProperty("token.secret"))
                    .parseClaimsJws(token)
                    .getBody()
                    .getSubject();
            if(userId == null) {
                return null;
            }
            
        return new UsernamePasswordAuthenticationToken(userId, null, new ArrayList<>());
    }
    
}

我希望此代码对您有用

bq3bfh9z

bq3bfh9z5#

你好,新版本的spring Boot 3和jjwt版本0.11.5,这对我来说很好:
final var subject = Jwts.parserBuilder().setSigningKey(Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret))).build().parseClaimsJws(token).getBody().getSubject();

相关问题