Quantcast
Channel: Active questions tagged servlets - Stack Overflow
Viewing all articles
Browse latest Browse all 675

how to add custom field in the httpServlerResponse for jwt filter

$
0
0

i am have react js and springboot 2.5.x application, for authorization i am using jwt sping security.

i have a requirement of when application (java process) restarts need to clear the user session and force the user to login page.

for that requirement i simply taking a timestamp variable and while login adding the timestamp to the jwt payload.

when application restarts i am updating the variable so when user try to reload the page or navigates to other page this timestamp will missmatch and its working fine.

now i am trying to add a custom json field like (isValidTokenVersion:true or false) to the HttpServletResponse of jwt response but its not adding

can you help me with this

JwtTokenUtil.java

package com.demo.services.Authentication;import com.demo.model.Users;import io.jsonwebtoken.Claims;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.stereotype.Component;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.function.Function;@Componentpublic class JwtTokenUtil {    private final String secret = "secret";     private final long expiration = 24 * 60 * 60 * 1000; // Token expiration in milliseconds (24 hours)    private long tokenVersion = System.currentTimeMillis();    private boolean isTokenExpired = false;    public String generateToken(Users userDetails) {        Map<String, Object> claims = new HashMap<>();        claims.put("version", tokenVersion);        //Generating Token for authentication.        return Jwts.builder()                .setClaims(claims)                .setSubject(userDetails.getUsername())                .setIssuedAt(new Date())                .setExpiration(new Date(System.currentTimeMillis() + expiration))                .signWith(SignatureAlgorithm.HS512, secret)                .compact();    }    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).parseClaimsJws(token).getBody();    }    private Boolean isTokenExpired(String token) {        return extractExpiration(token).before(new Date());    }    public Boolean validateToken(String token, UserDetails userDetails) {        final String username = extractUsername(token);        final long tokenVersion = extractClaim(token, claims -> claims.get("version", Long.class));        boolean validToken = false;        if(username.equals(userDetails.getUsername()) && !isTokenExpired(token) && tokenVersion == this.tokenVersion){            validToken = true;            isTokenExpired = false;        }else{            validToken = false;            if(tokenVersion != this.tokenVersion){                isTokenExpired = true;            }        }        return validToken;    }    public void updateTokenVersion() {        this.tokenVersion = System.currentTimeMillis();    }    public boolean isTokenExpired() {        return isTokenExpired;    }}

AuthenticationService.java

package com.demo.services.Authentication;import com.demo.model.Users;import com.demo.repository.UsersRepository;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;import java.util.ArrayList;import java.util.Optional;@Servicepublic class AuthenticationService implements UserDetailsService {    @Autowired    private UsersRepository usersRepository;    @Autowired    private PasswordEncoder passwordEncoder;    @Autowired    private JwtTokenUtil jwttUtil;    private static final Logger log = LogManager.getLogger(AuthenticationService.class);public void authenticate(String username, String password, HttpServletResponse response) {    try {        Optional<Users> user = usersRepository.findById(username);        JSONObject json = new JSONObject();        //Checking username and password.        if (user.isPresent() && new BCryptPasswordEncoder().matches(password, user.get().getPassword())) {            //Generating JWT token.            String token = jwttUtil.generateToken(user.get());            if (token != null && !token.isEmpty()) {                json.put("response", "success");                json.put("token", token);                log.error("User logged in Successfully.");            } else {                json.put("response", "failed");                log.error("Internal Server error while validating user credentials ");            }        } else {            json.put("response", "failed");            log.error("Invalid Credentials Passed. ");        }        sendResponseToReq(json.toString(), response, 200);    } catch (Exception e) {        log.error("Exception While Authenticating User " + e);    }}private void sendResponseToReq(String result, HttpServletResponse response, int respCode) {    try {        response.setStatus(respCode);        response.setContentLength(result.length());        response.getWriter().write(result);    } catch (Exception e) {        // Handle any exceptions that occurred while sending the response        e.printStackTrace();    }}@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {    Users user = usersRepository.findByUsername(s);    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());}public void resetTokenVersion(){    try{        jwttUtil.updateTokenVersion();    }catch (Exception e){        log.error("Unable to reset Token Version ",e);    }}}

JwtFilter.java

package com.demo.services.Authentication;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Componentpublic class JwtFilter extends OncePerRequestFilter {    @Autowired    private JwtTokenUtil jwtUtil;    @Autowired    private AuthenticationService service;    @Override    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {        String authorizationHeader = httpServletRequest.getHeader("Authorization");        String token = null;        String userName = null;        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {            token = authorizationHeader.substring(7);            userName = jwtUtil.extractUsername(token);        }        if (userName != null && SecurityContextHolder.getContext().getAuthentication() == null) {            UserDetails userDetails = service.loadUserByUsername(userName);            if (jwtUtil.validateToken(token, userDetails)) {                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());                usernamePasswordAuthenticationToken                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);            }else if(jwtUtil.isTokenExpired()){                JSONObject json = new JSONObject();                json.put("invalidTokenVersion", true);                httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);                httpServletResponse.setContentType("application/json");                httpServletResponse.getWriter().write(json.toString());            }        }        filterChain.doFilter(httpServletRequest, httpServletResponse);    }}

and also tried some more things like

httpServletResponse.setHeader("Custom-Header-Name", "Custom-Value");package com.demo.services.Authentication;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;public class MyResponseRequestWrapper extends HttpServletResponseWrapper{    public MyResponseRequestWrapper(HttpServletResponse response) {        super(response);    }}HttpServletResponse myResponse = (HttpServletResponse) response;    MyResponseRequestWrapper responseWrapper = new MyResponseRequestWrapper(myResponse);    responseWrapper.addHeader("customHeader", "customValue");    filterChain.doFilter(request, myResponse);

this is what i tried please help

thanks


Viewing all articles
Browse latest Browse all 675

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>