Generate JSON Web token - java

I have this class to generate a JSON Web token with I got from this post.
I need an id and a expression date to create a token.
Do I have to set up some kind of server to get the id and the expression date?
/**
* Provides static methods for creating and verifying access tokens and such.
*
* #author davidm
*
*/
public class AuthHelper {
private static final String AUDIENCE = "NotReallyImportant";
private static final String ISSUER = "crazyquote";
private static final String SIGNING_KEY = "LongAndHardToGuessValueWithSpecialCharacters#^($%*$%";
/**
* Creates a json web token which is a digitally signed token that contains
* a payload (e.g. userId to identify the user). The signing key is secret.
* That ensures that the token is authentic and has not been modified. Using
* a jwt eliminates the need to store authentication session information in
* a database.
*
* #param userId
* #param durationDays
* #return
*/
public static String createJsonWebToken(String userId, Long durationDays) {
// Current time and signing algorithm
Calendar cal = Calendar.getInstance();
HmacSHA256Signer signer;
try {
signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes());
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
// Configure JSON token
JsonToken token = new net.oauth.jsontoken.JsonToken(signer);
token.setAudience(AUDIENCE);
token.setIssuedAt(new org.joda.time.Instant(cal.getTimeInMillis()));
token.setExpiration(new org.joda.time.Instant(cal.getTimeInMillis()
+ 1000L * 60L * 60L * 24L * durationDays));
// Configure request object, which provides information of the item
JsonObject request = new JsonObject();
request.addProperty("userId", userId);
System.out.println("request " + request);
JsonObject payload = token.getPayloadAsJsonObject();
payload.add("info", request);
try {
return token.serializeAndSign();
} catch (SignatureException e) {
throw new RuntimeException(e);
}
}
/**
* Verifies a json web token's validity and extracts the user id and other
* information from it.
*
* #param token
* #return
* #throws SignatureException
* #throws InvalidKeyException
*/
public static TokenInfo verifyToken(String token) {
try {
final Verifier hmacVerifier = new HmacSHA256Verifier(
SIGNING_KEY.getBytes());
VerifierProvider hmacLocator = new VerifierProvider() {
#Override
public List<Verifier> findVerifier(String id, String key) {
return Lists.newArrayList(hmacVerifier);
}
};
VerifierProviders locators = new VerifierProviders();
locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator);
net.oauth.jsontoken.Checker checker = new net.oauth.jsontoken.Checker() {
#Override
public void check(JsonObject payload) throws SignatureException {
// don't throw - allow anything
}
};
// Ignore Audience does not mean that the Signature is ignored
JsonTokenParser parser = new JsonTokenParser(locators, checker);
JsonToken jt;
try {
jt = parser.verifyAndDeserialize(token);
} catch (SignatureException e) {
throw new RuntimeException(e);
}
JsonObject payload = jt.getPayloadAsJsonObject();
TokenInfo t = new TokenInfo();
String issuer = payload.getAsJsonPrimitive("iss").getAsString();
String userIdString = payload.getAsJsonObject("info")
.getAsJsonPrimitive("userId").getAsString();
if (issuer.equals(ISSUER) && !StringUtils.isBlank(userIdString)) {
t.setUserId(new ObjectId(userIdString));
t.setIssued(new DateTime(payload.getAsJsonPrimitive("iat")
.getAsLong()));
t.setExpires(new DateTime(payload.getAsJsonPrimitive("exp")
.getAsLong()));
return t;
} else {
return null;
}
} catch (InvalidKeyException e1) {
throw new RuntimeException(e1);
}
}
}

I would expect the user's ID in this context is either the username sent to the application by the user themselves, or some other kind of ID that you can look up based on the principal the user sent. The expiration date you simply choose. How long do you want the token to be valid before the user has to relogin? Now, on the topic of servers, there's nothing in the OAuth2 protocol mandating a server or a web context. What kind of application are you building?

Related

Spring RestService - target invocation exception

I'm trying to invoke a service using Spring's RestOperations class, but am getting a target invocation exception on the line where it invokes rest.getForObject. This is the method where the exception gets thrown:
#Override
#SuppressWarnings("unchecked")
public List<INorcaSummarySystemDTO> getNorcaSummaryBySystem(String systemName, Date fromDate){
List<INorcaSummarySystemDTO> norcaSummarySystem = new ArrayList<>();
try {
URI uri = UriComponentsBuilder.fromUriString(configuration.getDacqUrl() +
"/fa/api/v1/facility/1/norcasummarysystem")
.build().toUri();
NorcaSummarySystemDTO[] list = rest.getForObject(uri.toString(), NorcaSummarySystemDTO[].class);
norcaSummarySystem = Arrays.asList(list);
} catch (RestClientException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Exception while getting Norca summary system. Error: {}", e.getMessage());
LOG.trace(e.getMessage(), e);
}
return null;
}
return norcaSummarySystem;
}
The URI that it's invoking works when I call it from postman:
http://localhost:8181/fa/api/v1/facility/1/norcasummarysystem
Here's a picture of it in the debugger:
I'm modeling the call from another class which does the same thing, i.e. uses the rest client to return a list array of DTOs, based on the two lines in particular:
BarcodeDataDTO[] barcodeData = restClient.getForObject(uri.toString(), BarcodeDataDTO[].class);
dacqBarcodeDataDTOS = Arrays.asList(barcodeData);
This is the full method from that class:
List<BarcodeDataDTO> dacqBarcodeDataDTOS;
try {
URI uri = UriComponentsBuilder
.fromUriString(
servicesConfiguration.getDacqUrl() +API_V1_PATH + Constants.URI_FACILITY +
facility.getFacilityName() + Constants.URI_SYSTEM +
URLEncoder.encode(system.getSystemName(),StandardCharsets.UTF_8) +
Constants.URI_OBJECT + objectId + Constants.URI_BARCODES)
.queryParam(Constants.SCAN_TIME, DATE_TIME_FORMATTER.format(scanTime)).build().toUri();
BarcodeDataDTO[] barcodeData = restClient.getForObject(uri.toString(), BarcodeDataDTO[].class);
dacqBarcodeDataDTOS = Arrays.asList(barcodeData);
} catch (RestClientException restException) {
LOGGER.error(restException.getMessage(), restException);
return Collections.emptyList();
} catch (Exception e) {
throw new ConnectionFailureException(
"Fail to fetch barcode data from data aquisition layer. The exception is: " + e);
}
This is the code for the RestController being invoked:
package com.sick.ilcore.dacq.controller;
/**
* <p>NorcaSummaryController class.</p>
*
*/
#CrossOrigin
#RestController
#RequestMapping(CommonConstants.API_V1 + "/facility/{facilityName}")
public class NorcaSummaryController {
#Autowired
private IBarcodeDataService barcodedataService;
/**
*
* #param system name
* #param fromDate - optional from date in yyyy-MM-dd format
*
* #return NORCA totals by system
*/
#GetMapping(value = "/norcasummarysystem")
private List<INorcaSummarySystemDTO> getNorcaSummaryBySystem(
#RequestParam("systemName") Optional<String> systemName,
#RequestParam("fromDate") #DateTimeFormat(pattern="yyyy-MM-dd") Optional<Date> fromDate) {
String systemNameVal = null;
if (systemName.isPresent()) {
systemNameVal = systemName.get();
}
else {
systemNameVal = "all";
}
Date fromDateVal = DACQUtils.calcFromDateVal(fromDate);
List<INorcaSummarySystemDTO> norcaList = barcodedataService.getNorcaSummaryBySystem(systemNameVal, fromDateVal);
return norcaList;
}
The problem turned out to be a jackson exception that showed up after a couple of hours. A quick google revealed that I had to add a default constructor to the DTOs.

scan IP without SNMP agent

Using as an example a following code from https://www.jitendrazaa.com/blog/java/snmp/create-snmp-client-in-java-using-snmp4j/ to monitor a network when I send OIDs to an empty IP or to a device without SNMP the program throws an exception.
I use a for loop to read IPs. I have tried to change the flow of execution in different ways without success.
the program falls in the getAsStrint method with java.lang.NullPointerException
public class SNMPManager {
Snmp snmp = null;
String address = null;
/**
* Constructor
*
* #param add
*/
public SNMPManager(String add) {
address = add;
}
public static void main(String[] args) throws IOException {
/**
* Port 161 is used for Read and Other operations
* Port 162 is used for the trap generation
*/
for (int i = 37; i < 40; i++) {
System.out.println("ip x.x.x." + i);
SNMPManager client = new SNMPManager("udp:192.168.1." + i + "/161");
//SNMPManager client = new SNMPManager("udp:192.168.1.37/161");
client.start();
/**
* OID - .1.3.6.1.2.1.1.1.0 => SysDec
* OID - .1.3.6.1.2.1.1.5.0 => SysName
* => MIB explorer will be usefull here, as discussed in previous article
*/
String sysDescr = client.getAsString(new OID(".1.3.6.1.2.1.1.5.0"));
System.out.println(".1.3.6.1.2.1.1.5.0" + " - SysName: " + sysDescr);
String sysDescr2 = client.getAsString(new OID(".1.3.6.1.2.1.1.1.0"));
System.out.println(".1.3.6.1.2.1.1.1.0" + " - SysDec: " + sysDescr2);
}
}
/**
* Start the Snmp session. If you forget the listen() method you will not
* get any answers because the communication is asynchronous
* and the listen() method listens for answers.
*
* #throws IOException
*/
private void start() throws IOException {
TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
// Do not forget this line!
transport.listen();
}
/**
* Method which takes a single OID and returns the response from the agent as a String.
*
* #param oid
* #return
* #throws IOException
*/
public String getAsString(OID oid) throws IOException {
ResponseEvent event = get(new OID[]{oid});
return event.getResponse().get(0).getVariable().toString();
}
/**
* This method is capable of handling multiple OIDs
*
* #param oids
* #return
* #throws IOException
*/
public ResponseEvent get(OID oids[]) throws IOException {
PDU pdu = new PDU();
for (OID oid : oids) {
pdu.add(new VariableBinding(oid));
}
pdu.setType(PDU.GET);
ResponseEvent event = snmp.send(pdu, getTarget(), null);
if (event != null) {
return event;
}
throw new RuntimeException("GET timed out");
}
/**
* This method returns a Target, which contains information about
* where the data should be fetched and how.
*
* #return
*/
private Target getTarget() {
Address targetAddress = GenericAddress.parse(address);
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version2c);
return target;
}
make getAsString(OID oid) method like this
public String getAsString(OID oid) throws IOException {
ResponseEvent event = get(new OID[]{oid});
if(event.getResponse() != null){
return event.getResponse().get(0).getVariable().toString();
} else {
return "no target"
}
}
there are no target that is why null pointer exception

Spring RestTemplate exchange throws UnhandledHttpStatusException

Overview:
I am going to use RestTemplate to invoke a get request from external REST webservice.
My code is as follows:
#Slf4j
#Component("AccMemberDetailsApiControllerImpl")
public class AccMemberDetailsApiControllerImpl implements MemberDetailsApiController {
private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type";
private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
private static final String USERID_PARAMETER_NAME = "userId";
private static final String VEHICLEID_PARAMETER_NAME = "vehicleId";
private static final ObjectMapper mapper = new ObjectMapper();
/**
* This constant is used to check whether or not the response from ACC is an empty JSON string
*/
private static final String EMPTY_RESPONSE = "{}";
#Value("${com.blss.memberServices.provider.posServiceURL}")
private String accPosServiceURL;
#Autowired
private RestTemplate restTemplate;
#Autowired
private AccTokenUtility accTokenUtility;
#Autowired
private ResourceMessage resourceMessage;
void setAccTokenUtility(AccTokenUtility accTokenUtility) {
this.accTokenUtility = accTokenUtility;
}
void setResourceMessage(ResourceMessage resourceMessage) {
this.resourceMessage = resourceMessage;
}
/**
* #see MemberDetailsApiController#getMemberDetails(String, String)
*/
#Override
public MemberDetailsModel getMemberDetails(String storeId, String membershipIdentifier) {
/**
* Getting CAD token
*/
String token = accTokenUtility.getCadToken();
/**
* Preparing the request
*/
HttpHeaders headers = new HttpHeaders();
// headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.set(CONTENT_TYPE_HEADER_NAME, MediaType.APPLICATION_JSON_VALUE);
headers.set(AUTHORIZATION_HEADER_NAME, token);
HttpEntity<String> entity = new HttpEntity<>(headers);
/**
* Creating the dispatch URL by means of userId and vehicleId
*/
String dispatchURL = accPosServiceURL + "DispatchedEvent/{userId}/{vehicleId}";
/**
* Creating the URL variables and being valued by corresponding method parameters
*/
Map<String, String> parameters = new HashMap<>();
// parameters.put(USERID_PARAMETER_NAME, storeId);
parameters.put(USERID_PARAMETER_NAME, "mr2");
// parameters.put(VEHICLEID_PARAMETER_NAME, membershipIdentifier);
parameters.put(VEHICLEID_PARAMETER_NAME, "VEH1");
/**
* Calling the rest webservice and returning response with body of type {#link AccMemberDetails}
*/
ResponseEntity<String> response;
MemberDetailsModel memberDetailsModel = null;
AccMemberDetails accMemberDetails;
try {
response = restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);
if (response == null || StringUtils.isBlank(response.getBody()) || EMPTY_RESPONSE.equals(response.getBody())) {
throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier));
} else {
accMemberDetails = deserialize(response.getBody(), AccMemberDetails.class);
String accErrorMessage = accMemberDetails.getUserMessage();
if (!StringUtils.isBlank(accErrorMessage)) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MESSAGE_FROM_API, "ACC", accErrorMessage));
}
memberDetailsModel = convert(accMemberDetails);
}
} catch (RestClientException e) {
handleExceptions(e, storeId, membershipIdentifier);
}
return memberDetailsModel;
}
/**
* This method is responsible for deserializing string REST response into an object of type {#link AccMemberDetails}
*/
<T> T deserialize(final String response, final Class<T> responseClass) {
try {
return mapper.readValue(response, responseClass);
} catch (IOException e) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MAP_RESPONSE_OBJECT), e);
}
}
/**
* This method is responsible for converting an instance of type {#link AccMemberDetails} to an instance of type
* {#link MemberDetailsModel}
*
* #param accMemberDetails an instance of type {#link AccMemberDetails}
* #return an instance of type {#link MemberDetailsModel}
*/
MemberDetailsModel convert(AccMemberDetails accMemberDetails) {
MemberDetailsModel memberDetailsModel = new MemberDetailsModel();
memberDetailsModel.setEventId(accMemberDetails.getEventId());
memberDetailsModel.setMemberName(accMemberDetails.getMemberName());
memberDetailsModel.setMembershipNumber(accMemberDetails.getMembershipNumber());
memberDetailsModel.setMembershipLevel(accMemberDetails.getPricingLevel());
return memberDetailsModel;
}
/**
* This method is responsible for handling Exceptions may be thrown by ACC REST webservice
*
* #param e an instance of type {#link RestClientException}
* #param storeId an instance of type {#link String} and used in building exception messages
* #param membershipIdentifier an instance of type {#link String} and used in building exception messages
*/
private void handleExceptions(RestClientException e, String storeId, String membershipIdentifier) {
if (e instanceof HttpStatusCodeException) {
HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) e;
HttpStatus httpStatusCode = httpStatusCodeException.getStatusCode();
if (404 == httpStatusCode.value()) {
throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier), e);
} else if (500 == httpStatusCode.value()) {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_SERVER_ERROR, "ACC"), e);
} else {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_HTTP_STATUS_CODE_ERROR, "HttpStatusCodeException", "ACC"), e);
}
} else {
throw new InternalServerException(resourceMessage.getMessage(MEMBER_REST_CLIENT_ERROR, "RestClientException", "ACC"), e);
}
}
Problem
However I got UnhandledHttpStatusException after calling "restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);" in the code snippet. the exception stack trace is as follows:
Caused by: org.springframework.web.client.UnknownHttpStatusCodeException: Unknown status code [443] null
at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:60)
at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:629)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:565)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:484)
at com.blss.retailServices.memberServices.controllers.impl.acc.AccMemberDetailsApiControllerImpl.getMemberDetails(AccMemberDetailsApiControllerImpl.java:110)
Now I would be grateful if anyone could suggest me a solution.
I called this webservice with curl by using "-v" in order to get more info in response. As a result, I got the same exception (443) from their side. So, It sounds like they should have a better exception handler to return meaningful exception messages.

Getting email text from ImageHtmlEmail

We are using apache commons mail, specifically the ImageHtmlEmail. We really would like to log every email sent - exactly as it will be sent - in the perfect world it would be something you could paste into sendmail - with all headers and other information included.
This is primarily to troubleshoot some problems we've been having with it turning up as text/plain rather than text/html - but also because it would be nice to have a record of exactly what the system sent out stored in our logs.
So essentially - the dream is a function that would take an ImageHtmlEmail and return a string - as it will be sent. I know I could render it into a string myself, but then I'm bypassing whatever is being done in the library function, which is what we really want to capture. I tried BuildMimeMessage and then getMimeMessage, which I think is probably the correct first step - but that just leaves me with the question of how to turn a mimemessage into a string.
I have a sort of solution - but would love a better one:
/**
* add content of this type
*
* #param builder
* #param content
*/
private static void addContent(final StringBuilder builder, final Object content)
{
try
{
if (content instanceof MimeMultipart)
{
final MimeMultipart multi = (MimeMultipart) content;
for (int i = 0; i < multi.getCount(); i++)
{
addContent(builder, ((MimeMultipart) content).getBodyPart(i));
}
}
else if (content instanceof MimeBodyPart)
{
final MimeBodyPart message = (MimeBodyPart) content;
final Enumeration<?> headers = message.getAllHeaderLines();
while (headers.hasMoreElements())
{
final String line = (String) headers.nextElement();
builder.append(line).append("\n");
}
addContent(builder, message.getContent());
}
else if (content instanceof String)
{
builder.append((String) content).append("\n");
}
else
{
System.out.println(content.getClass().getName());
throw CommonException.notImplementedYet();
}
}
catch (final Exception theException)
{
throw CommonException.insteadOf(theException);
}
}
/**
* get a string from an email
*
* #param email
* #return
*/
public static String fromHtmlEmail(final ImageHtmlEmail email)
{
return fromMimeMessage(email.getMimeMessage());
}
/**
* #param message
* #return a string from a mime message
*/
private static String fromMimeMessage(final MimeMessage message)
{
try
{
message.saveChanges();
final StringBuilder output = new StringBuilder();
final Enumeration<?> headers = message.getAllHeaderLines();
while (headers.hasMoreElements())
{
final String line = (String) headers.nextElement();
output.append(line).append("\n");
}
addContent(output, message.getContent());
return output.toString();
}
catch (final Exception theException)
{
throw CommonException.insteadOf(theException);
}
}
}

How to do polling and get the incoming messages in a database

The incoming data has to be fed back into the polling method and also should be processed further for another class.
public List<KAAMessage> fullPoll() throws Exception {
Statement st = dbConnection.createStatement();
ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION = 804 order by SEQ DESC");
List<KpiMessage> pojoCol = new ArrayList<KpiMessage>();
while (rs.next()) {
KpiMessage filedClass = convertRecordsetToPojo(rs);
pojoCol.add(filedClass);
}
return pojoCol;
}
/**
* Converts a provided record-set to a {#link KpiMessage}.
*
* The following attributes are copied from record-set to pojo:
*
* <ul>
* <li>SEQ</li>
* <li>TABLENAME</li>
* <li>ENTRYTIME</li>
* <li>STATUS</li>
* </ul>
*
* #param rs
* the record-set to convert
* #return the converted pojo class object
* #throws SQLException
* if an sql error occurs during processing of recordset
*/
private KpiMessage convertRecordsetToPojo(ResultSet rs) throws SQLException {
KpiMessage msg = new KpiMessage();
int sequence = rs.getInt("SEQ");
msg.setSequence(sequence);
int action = rs.getInt("ACTION");
msg.setAction(action);
String tablename = rs.getString("TABLENAME");
msg.setTableName(tablename);
Timestamp entrytime = rs.getTimestamp("ENTRYTIME");
Date entryTime = new Date(entrytime.getTime());
msg.setEntryTime(entryTime);
Timestamp processingtime = rs.getTimestamp("PROCESSINGTIME");
if (processingtime != null) {
Date processingTime = new Date(processingtime.getTime());
msg.setProcessingTime(processingTime);
}
String keyInfo1 = rs.getString("KEYINFO1");
msg.setKeyInfo1(keyInfo1);
String keyInfo2 = rs.getString("KEYINFO2");
msg.setKeyInfo2(keyInfo2);
return msg;
}
This class has the Poll() method which reads message from the database. In the database I have SequeceID as unique number and it keeps on increasing for new data, but how can I get this new messages and feed it back to polling?
P.S: Please comment if you are down voting or closing my post because I am new here and I'd like to know the details.
this the Controller Class which runs the thread for the Poll() method.
public class RunnableController {
/** Here This Queue initializes the DB and have the collection of incoming message
*
*/
private static Collection<KaMessage> incomingQueue = new ArrayList<KAMessage>();
private Connection dbConncetion;
private ExecutorService threadExecutor;
private void initializeDb()
{
//catching exception must be adapted - generic type Exception prohibited
DBhandler con = new DBhandler();
try {
dbConncetion = con.initializeDB();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initialiseThreads()
{
try {
threadExecutor = Executors.newFixedThreadPool(10);
PollingSynchronizer read = new PollingSynchronizer(incomingQueue,
dbConncetion);
threadExecutor.submit(read);
}catch (Exception e){
e.printStackTrace();
}
}
private void shutDownThreads()
{
try {
threadExecutor.shutdown();
dbConncetion.close();
}catch (Exception e){
e.printStackTrace();
}
}
/** Here This Queue passes the messages and have the collection of outgoing message
*
*/
// private Collection<KpiMessage> outgingQueue = new ArrayList<KpiMessage>();
/**
* Main
*
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
RunnableController controller = new RunnableController();
System.out.println(incomingQueue.size());
controller.initializeDb();
controller.initialiseThreads();
System.out.println("Repetetive polling for each 6 seconds");
KpiProcessor kp = new KpiProcessor();
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}

Categories

Resources