/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.gateway.services.security.token.impl;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class JWTToken implements JWT {
private static JWTProviderMessages log = MessagesFactory.get( JWTProviderMessages.class );
SignedJWT jwt = null;
private JWTToken(byte[] header, byte[] claims, byte[] signature) throws ParseException {
try {
jwt = new SignedJWT(new Base64URL(new String(header, "UTF8")), new Base64URL(new String(claims, "UTF8")),
new Base64URL(new String(signature, "UTF8")));
} catch (UnsupportedEncodingException e) {
log.unsupportedEncoding(e);
}
}
public JWTToken(String serializedJWT) {
try {
jwt = SignedJWT.parse(serializedJWT);
} catch (ParseException e) {
log.unableToParseToken(e);
}
}
public JWTToken(String alg, String[] claimsArray) {
this(alg, claimsArray, null);
}
public JWTToken(String alg, String[] claimsArray, List<String> audiences) {
JWSHeader header = new JWSHeader(new JWSAlgorithm(alg));
if (claimsArray[2] != null) {
if (audiences == null) {
audiences = new ArrayList<String>();
}
audiences.add(claimsArray[2]);
}
JWTClaimsSet claims = null;
JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
.issuer(claimsArray[0])
.subject(claimsArray[1])
.audience(audiences);
if(claimsArray[3] != null) {
builder = builder.expirationTime(new Date(Long.parseLong(claimsArray[3])));
}
claims = builder.build();
jwt = new SignedJWT(header, claims);
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPayloadToSign()
*/
@Override
public String getHeader() {
JWSHeader header = jwt.getHeader();
return header.toString();
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPayloadToSign()
*/
@Override
public String getClaims() {
String c = null;
JWTClaimsSet claims = null;
try {
claims = (JWTClaimsSet) jwt.getJWTClaimsSet();
c = claims.toJSONObject().toJSONString();
} catch (ParseException e) {
log.unableToParseToken(e);
}
return c;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPayloadToSign()
*/
@Override
public String getPayload() {
Payload payload = jwt.getPayload();
return payload.toString();
}
public String toString() {
return jwt.serialize();
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#setSignaturePayload(byte[])
*/
@Override
public void setSignaturePayload(byte[] payload) {
// this.payload = payload;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getSignaturePayload()
*/
@Override
public byte[] getSignaturePayload() {
byte[] b = null;
Base64URL b64 = jwt.getSignature();
if (b64 != null) {
b = b64.decode();
}
return b;
}
public static JWTToken parseToken(String wireToken) throws ParseException {
log.parsingToken(wireToken);
String[] parts = wireToken.split("\\.");
JWTToken jwt = new JWTToken(Base64.decodeBase64(parts[0]), Base64.decodeBase64(parts[1]), Base64.decodeBase64(parts[2]));
// System.out.println("header: " + token.header);
// System.out.println("claims: " + token.claims);
// System.out.println("payload: " + new String(token.payload));
return jwt;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getClaim(java.lang.String)
*/
@Override
public String getClaim(String claimName) {
String claim = null;
try {
claim = jwt.getJWTClaimsSet().getStringClaim(claimName);
} catch (ParseException e) {
log.unableToParseToken(e);
}
return claim;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getSubject()
*/
@Override
public String getSubject() {
return getClaim(JWT.SUBJECT);
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getIssuer()
*/
@Override
public String getIssuer() {
return getClaim(JWT.ISSUER);
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getAudience()
*/
@Override
public String getAudience() {
String[] claim = null;
String c = null;
claim = getAudienceClaims();
if (claim != null) {
c = claim[0];
}
return c;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getAudienceClaims()
*/
@Override
public String[] getAudienceClaims() {
String[] claims = null;
try {
claims = jwt.getJWTClaimsSet().getStringArrayClaim(JWT.AUDIENCE);
} catch (ParseException e) {
log.unableToParseToken(e);
}
return claims;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getExpires()
*/
@Override
public String getExpires() {
return getClaim(JWT.EXPIRES);
}
@Override
public Date getExpiresDate() {
Date date = null;
try {
date = jwt.getJWTClaimsSet().getExpirationTime();
} catch (ParseException e) {
log.unableToParseToken(e);
}
return date;
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPrincipal()
*/
@Override
public String getPrincipal() {
return getClaim(JWT.PRINCIPAL);
}
/* (non-Javadoc)
* @see org.apache.hadoop.gateway.services.security.token.impl.JWT#getPrincipal()
*/
@Override
public void sign(JWSSigner signer) {
try {
jwt.sign(signer);
} catch (JOSEException e) {
log.unableToSignToken(e);
}
}
/**
* @param verifier
* @return
*/
public boolean verify(JWSVerifier verifier) {
boolean rc = false;
try {
rc = jwt.verify(verifier);
} catch (JOSEException e) {
// TODO Auto-generated catch block
log.unableToVerifyToken(e);
}
return rc;
}
}