com.jevontech.wabl.security.TokenUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.jevontech.wabl.security.TokenUtils.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jevontech.wabl.security;

import com.jevontech.wabl.services.WablConfigurationService;
import com.jevontech.wabl.entities.SecurityUser;
import io.jsonwebtoken.*;
import java.io.UnsupportedEncodingException;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mobile.device.Device;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Component
public class TokenUtils {

    private final Logger logger = Logger.getLogger(this.getClass());

    private static final String AUDIENCE_UNKNOWN = "unknown";
    private static final String AUDIENCE_WEB = "web";
    private static final String AUDIENCE_MOBILE = "mobile";
    private static final String AUDIENCE_TABLET = "tablet";

    private final String SUB = "sub";
    private final String CREATED = "created";
    private final String AUDIENCE = "audience";

    @Autowired
    WablConfigurationService configurationService;

    public String getUsernameFromToken(String token) {
        String username;

        final Claims claims = this.getClaimsFromToken(token);

        if (claims != null) {
            username = claims.getSubject();
        } else {
            username = null;
        }
        return username;
    }

    public Date getCreatedDateFromToken(String token) {
        Date created;

        final Claims claims = this.getClaimsFromToken(token);
        if (claims != null) {
            created = new Date((Long) claims.get(this.CREATED));
        } else {
            created = null;
        }
        return created;
    }

    public Date getExpirationDateFromToken(String token) {
        Date expiration;

        final Claims claims = this.getClaimsFromToken(token);
        if (claims != null) {
            expiration = claims.getExpiration();
        } else {
            expiration = null;
        }
        return expiration;
    }

    public String getAudienceFromToken(String token) {
        String audience;

        final Claims claims = this.getClaimsFromToken(token);
        if (claims != null) {
            audience = (String) claims.get(this.AUDIENCE);
        } else {
            audience = null;
        }
        return audience;
    }

    private Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(configurationService.getSecret().getBytes("UTF-8"))
                    .parseClaimsJws(token).getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }

    private Date generateCurrentDate() {
        return new Date(System.currentTimeMillis());
    }

    private Date generateExpirationDate() {
        long experationTime = configurationService.getExpirationTime() * 1000;
        return new Date(System.currentTimeMillis() + experationTime);
    }

    private Boolean isTokenExpired(String token) {
        final Date expiration = this.getExpirationDateFromToken(token);
        return expiration.before(this.generateCurrentDate());
    }

    private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
        return (lastPasswordReset != null && created.before(lastPasswordReset));
    }

    private String generateAudience(Device device) {
        String audience = this.AUDIENCE_UNKNOWN;
        if (device.isNormal()) {
            audience = this.AUDIENCE_WEB;
        } else if (device.isTablet()) {
            audience = AUDIENCE_TABLET;
        } else if (device.isMobile()) {
            audience = AUDIENCE_MOBILE;
        }
        return audience;
    }

    private Boolean ignoreTokenExpiration(String token) {
        String audience = this.getAudienceFromToken(token);
        return (this.AUDIENCE_TABLET.equals(audience) || this.AUDIENCE_MOBILE.equals(audience));
    }

    public String generateToken(UserDetails userDetails, Device device) {
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put(this.SUB, userDetails.getUsername());
        claims.put(this.AUDIENCE, this.generateAudience(device));
        claims.put(this.CREATED, this.generateCurrentDate());
        return this.generateToken(claims);
    }

    private String generateToken(Map<String, Object> claims) {
        try {
            return Jwts.builder().setClaims(claims).setExpiration(this.generateExpirationDate())
                    .signWith(SignatureAlgorithm.HS512, configurationService.getSecret().getBytes("UTF-8"))
                    .compact();
        } catch (UnsupportedEncodingException ex) {
            //didn't want to have this method throw the exception, would rather log it and sign the token like it was before
            logger.warn(ex.getMessage());
            return Jwts.builder().setClaims(claims).setExpiration(this.generateExpirationDate())
                    .signWith(SignatureAlgorithm.HS512, configurationService.getSecret()).compact();
        }
    }

    public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
        final Date created = this.getCreatedDateFromToken(token);
        return (!(this.isCreatedBeforeLastPasswordReset(created, lastPasswordReset))
                && (!(this.isTokenExpired(token)) || this.ignoreTokenExpiration(token)));
    }

    public String refreshToken(String token) {
        String refreshedToken;

        final Claims claims = this.getClaimsFromToken(token);
        if (claims != null) {
            claims.put(this.CREATED, this.generateCurrentDate());
            refreshedToken = this.generateToken(claims);
        } else {
            refreshedToken = null;
        }
        return refreshedToken;
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        SecurityUser user = (SecurityUser) userDetails;
        final String username = this.getUsernameFromToken(token);
        final Date created = this.getCreatedDateFromToken(token);
        final Date expiration = this.getExpirationDateFromToken(token);

        boolean userNameValid = false;
        if (username != null) {
            userNameValid = username.equals(user.getUsername());
        }

        return (userNameValid && !(this.isTokenExpired(token))
                && !(this.isCreatedBeforeLastPasswordReset(created, user.getLastPasswordReset())));
    }

}