GSSException createCredential - java

Major edit: 2015-05-27: After some degree of success updated on where I'm currently stuck rather than leaving a rambling post....could really do with some pointers on this one - a little bogged down....
I'm running some code on a Linux app server (WebSphere) that needs to authenticate to an IIS web service which is configured for "Integrated Authentication", but I'm having some problems forming the Authorization: Negotiate token.
I should also say that I need to put this token into the HTTP header for a JAX-WS SOAP request that I will subsequently build. I know my SOAP request itself works because we were using WS-Security Username token profile previously and it worked fine - trying to swap to kerberos is proving difficult...
My problem is with initSecContext I think. It appears that on the first call the context is configured in "some" way and there is some returned token data, but .isEstablished is false. The problem I'm having is putting the initSecContext call into a loop - it seems IIS just closes the connection when I do this. Can anyone give me some pointers - I seem to be taking the approach used by other posters and the Oracle samples (although the IBM/WebSphere sample only makes a single initSecContext call and doesn't check .isEstablished which seems odd to me based on the Oracle documentation).
Anyway, the error I get is below (note the Ready: property seems to clearly say initSecContext needs to loop - to me at least);
[5/27/15 6:51:11:605 UTC] 0000004f SystemOut O INFO: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: After initSecContext:
--- GSSContext ---
Owner: domainuser#MYDOMAIN.COM
Peer: HTTP/iishost.mycorp.com
State: initialized
Lifetime: indefinite
Ready: no
Flags:
Confidentiality off
Delegation on
Integrity off
MutualAuthn on
ReplayDetection off
SequenceDetection off
DelegatedCred: unknown
--- End of GSSContext ---
[5/27/15 6:51:11:605 UTC] 0000004f SystemOut O INFO: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: Context is not established, trying again
[5/27/15 6:51:11:606 UTC] 0000004f SystemOut O ERROR: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: IOException during context establishment: Connection reset
My code is below;
LoginContext lc = getLoginContext(contextName);
final Subject subject = lc.getSubject();
String b64Token = (String) Subject.doAs(subject, new PrivilegedExceptionAction() {
#Override
public Object run() throws PrivilegedActionException, GSSException {
// Create socket to server
Socket socket;
DataInputStream inStream = null;
DataOutputStream outStream = null;
try {
socket = new Socket("iishost.mycorp.com", 443);
inStream = new DataInputStream(socket.getInputStream());
outStream = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
System.out.println("Exception setting up server sockets: " + ex.getMessage());
}
GSSName gssName = manager.createName(userName, GSSName.NT_USER_NAME, KRB5_MECH_OID);
GSSCredential gssCred = manager.createCredential(gssName.canonicalize(KRB5_MECH_OID),
GSSCredential.DEFAULT_LIFETIME,
KRB5_MECH_OID,
GSSCredential.INITIATE_ONLY);
gssCred.add(gssName, GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
SPNEGO_MECH_OID,
GSSCredential.INITIATE_ONLY);
GSSName gssServerName = manager.createName(servicePrincipal, KERBEROS_V5_PRINCIPAL_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(SPNEGO_MECH_OID),
SPNEGO_MECH_OID,
gssCred,
GSSContext.DEFAULT_LIFETIME);
clientContext.requestCredDeleg(true);
clientContext.requestMutualAuth(true);
byte[] token = new byte[0];
while (!clientContext.isEstablished()) {
try {
token = clientContext.initSecContext(token, 0, token.length);
// IF I LOOK AT token HERE THERE IS CERTAINLY TOKEN DATA THERE - .isEstablished IS STILL FALSE
outStream.writeInt(token.length);
outStream.write(token);
outStream.flush();
// Check if we're done
if (!clientContext.isEstablished()) {
token = new byte[inStream.readInt()];
inStream.readFully(token);
}
} catch (IOException ex) {
// THIS EXCEPTION IS THROWN ON SECOND ITERATION - LOOKS LIKE IIS CLOSES THE CONNECTION
System.out.println("IOException during context establishment: " + ex.getMessage());
}
}
String b64Token = Base64.encode(token);
clientContext.dispose(); // I'm assuming this won't invalidate the token in some way as I need to use it later
return b64Token;
}
});
This doc tells me I don't need to loop on initSecContext, but .isEstablished returns false for me: http://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.zseries.doc/ae/tsec_SPNEGO_token.html?cp=SS7K4U_8.5.5%2F1-3-0-20-4-0&lang=en
The Oracle docs tell me I should: https://docs.oracle.com/javase/7/docs/api/org/ietf/jgss/GSSContext.html
My only hesitation is that from the Oracle docs it seems like I'm starting the application conversation, but what I'm trying to do it obtain the token only & it's later on in my code when I will use JAX-WS to post my actual web service call (including the spnego/kerberos token in the http header) - is this the cause of my issue?

Just an update. I have this working now - my previous code was largely ok - it was just my understanding of how the Kerberos token would be added to the JAX-WS request. Turns out it's just a matter of attaching a Handler to the bindingProvider. The handler then obtains the Kerberos token and adds it to the header of the request - nice and easy.
Below is my working Handler which is added to the Handler chain obtained from a call to bindingProvider.getBinding().getHandlerChain()
public class HTTPKerberosHandler implements SOAPHandler<SOAPMessageContext> {
private final String contextName;
private final String servicePrincipal;
private static Oid KRB5_MECH_OID = null;
private static Oid SPNEGO_MECH_OID = null;
private static Oid KERBEROS_V5_PRINCIPAL_NAME = null;
final String className = this.getClass().getName();
static {
try {
KERBEROS_V5_PRINCIPAL_NAME = new Oid("1.2.840.113554.1.2.2.1");
KRB5_MECH_OID = new Oid("1.2.840.113554.1.2.2");
SPNEGO_MECH_OID = new Oid("1.3.6.1.5.5.2");
} catch (final GSSException ex) {
System.out.println("Exception creating mechOid's: " + ex.getMessage());
ex.printStackTrace();
}
}
public HTTPKerberosHandler(final String contextName, final String servicePrincipal) {
this.contextName = contextName;
this.servicePrincipal = servicePrincipal;
}
#Override
public Set<QName> getHeaders() {
return null;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
#Override
public void close(MessageContext context) {
// No action
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
if (((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY))) {
return handleRequest(context);
} else {
return handleResponse(context);
}
}
private boolean handleRequest(SOAPMessageContext context) {
byte[] token = getKerberosToken(contextName, servicePrincipal);
HashMap<String, String> sendTransportHeaders = new HashMap<String, String>();
sendTransportHeaders.put("Authorization", "Negotiate " + Base64.encode(token));
context.put(com.ibm.websphere.webservices.Constants.REQUEST_TRANSPORT_PROPERTIES, sendTransportHeaders);
return true;
}
private boolean handleResponse(SOAPMessageContext context) {
logger.logInformation(className, "handleResponse", "Inbound response detected");
return true;
}
public byte[] getKerberosToken(final String contextName, final String servicePrincipal) {
try {
LoginContext lc = getLoginContext(contextName);
final Subject subject = lc.getSubject();
byte[] token = (byte[]) Subject.doAs(subject, new PrivilegedExceptionAction() {
#Override
public Object run() throws PrivilegedActionException, GSSException {
final String methodName = "getKerberosToken/run";
final GSSManager manager = GSSManager.getInstance();
Set<Principal> principals = subject.getPrincipals();
Iterator it = principals.iterator();
String principalName = ((Principal) it.next()).getName();
logger.logInformation(className, methodName, "Using principal: [" + principalName + "]");
GSSName gssName = manager.createName(principalName, GSSName.NT_USER_NAME, KRB5_MECH_OID);
GSSCredential gssCred = manager.createCredential(gssName.canonicalize(KRB5_MECH_OID),
GSSCredential.DEFAULT_LIFETIME,
KRB5_MECH_OID,
GSSCredential.INITIATE_ONLY);
gssCred.add(gssName, GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
SPNEGO_MECH_OID,
GSSCredential.INITIATE_ONLY);
logger.logInformation(className, methodName, "Client TGT obtained: " + gssCred.toString());
GSSName gssServerName = manager.createName(servicePrincipal, GSSName.NT_USER_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(SPNEGO_MECH_OID),
SPNEGO_MECH_OID,
gssCred,
GSSContext.DEFAULT_LIFETIME);
logger.logInformation(className, methodName, "Service ticket obtained: " + clientContext.toString());
byte[] token = new byte[0];
token = clientContext.initSecContext(token, 0, token.length);
clientContext.dispose();
return token;
}
});
return token;
} catch (PrivilegedActionException ex) {
logger.logError(HTTPKerberosHandler.class.getName(), methodName, "PrivilegedActionException: " + ex.getMessage());
} catch (Exception ex) {
logger.logError(HTTPKerberosHandler.class.getName(), methodName, "Exception: " + ex.getMessage());
}
return null;
}
private LoginContext getLoginContext(String contextName) {
LoginContext lc = null;
try {
lc = new LoginContext(contextName);
lc.login();
} catch (LoginException le) {
logger.logError(HTTPKerberosHandler.class.getName(), methodName, "Login exception: [" + le.getMessage() + "]");
le.printStackTrace();
}
return lc;
}
}

Related

Java request filter doesnt work properly with consecutive requests

I'm working on a filter for my requests to the payara server. The idea is that the user is granted a authorization token with some minutes of valid time and the frontend uses this token for requests, for security reasons. Every request or route change in the frontend will request a new token for the backend that will update the token stored in the database with a new one and return this new token to the front. The problem is when I send multiple consecutive requests the filter doesn't work properly, the first refresh works just fine but if the second is issued in less than 10 seconds the session rescued from the database isn't updated with the new token. If I select the session in SQL developer the token is right, the problem is in the filter that seems to be not getting the last one.
the filter:
#Provider
#Secure
#RequestScoped
#Priority(Priorities.AUTHENTICATION)
public class AuthorizationRequestFilter implements ContainerRequestFilter {
#Inject
Security security;
#Inject
JPAService service;
#Inject
Select select;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (requestContext.getMethod().equals("OPTIONS")) {
// Se o método de requisição é OPTIONS, desconsiderar...
return;
}
// Executa os filtros nos requests diferentes de login
if (!requestContext.getUriInfo().getPath().contains("login")) {
String secret = service.getSecret();
String session = null;
String auth = null;
String token = null;
EuroSession euroSession = null;
try {
session = requestContext.getHeaderString("eurosession");
auth = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
System.out.println("AUTH " + auth);
// Resgata o Authorization
try {
if (!auth.startsWith("Bearer")) {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Tipo de Token inválido").build());
}
token = auth.substring("Bearer".length()).trim();
} catch (NullPointerException e) {
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Tipo de Autenticacao nao informada").build());
}
// Verifica se a sessão existe
euroSession = select.buscaEuroSession(session);
System.out.println("SESSION SELECTED");
// Compara authorization com o token da sessão
System.out.println("TOKEN: " + token + "\nSESSION TOKEN: " + euroSession.getTOKEN());
if (!select.buscaEuroSession(session).getTOKEN().equals(token)) { //if (!euroSession.getTOKEN().equals(token)) {
throw new IllegalArgumentException("Authorization não coincide com o token da sessão");
}
// Valida o refresh authorization
if (requestContext.getUriInfo().getPath().contains("refreshSession")) {
String refreshToken = requestContext.getHeaderString("refreshauthorization");
readToken(requestContext, secret, session, refreshToken, "refresh token inválido");
}
// Valida o Authorization token
readToken(requestContext, secret, session, token, "token inválido");
euroSession = null;
} catch (Exception ex) { // alterar o json de resposta
System.out.println("EXCEPTION " + ex);
JsonObject json = new JsonObject();
json.addProperty("serviceResponse", "ERROR");
json.addProperty("message", "Headers Inválidos");
json.addProperty("exception", ex.getMessage());
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity(json.toString()).build());
}
}
}
// Tenta ler o token
private void readToken(ContainerRequestContext requestContext, String secret, String session, String token, String message) {
try {
SecretKey secretKey = security.generateSecretKey(secret + session);
Jws jws = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
System.out.println("jws" + jws);
System.out.println("Body JWS: " + jws.getBody());
} catch (ExpiredJwtException | MalformedJwtException | UnsupportedJwtException | SignatureException | IllegalArgumentException | NoSuchAlgorithmException ex) {
System.out.println("EXCEPTION" + ex);
JsonObject json = new JsonObject();
json.addProperty("serviceResponse", "ERROR");
json.addProperty("message", message);
json.addProperty("exception", ex.getMessage());
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity(json.toString()).build());
}
}
private String getEntityBody(ContainerRequestContext requestContext) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = requestContext.getEntityStream();
final StringBuilder b = new StringBuilder();
try {
ReaderWriter.writeTo(in, out);
byte[] requestEntity = out.toByteArray();
b.append(new String(requestEntity)).append("\n");
requestContext.setEntityStream(new ByteArrayInputStream(requestEntity));
} catch (IOException ex) {
//Handle logging error
System.out.println("AccessControlRequestFilter.getEntityBody: IOException");
System.out.println(ex);
}
return b.toString();
}
}
the buscaEuroSession() that retrieves the session data from the database:
public EuroSession buscaEuroSession(String sessionUUID) {
EntityManager em = emf.createEntityManager();
String query = "SELECT PORTALID, IDSESSION, CREATEDAT, USERNAME, UUIDSESSION, EXPIREAT, TOKEN, REFRESHTOKEN FROM AD_PORTALEUROSESSION WHERE UUIDSESSION = (?) AND PORTALID = (SELECT MAX(PORTALID) FROM AD_PORTALEURO WHERE ATIVO = 'S')";
Query q = em.createNativeQuery(query, EuroSession.class);
q.setParameter(1, sessionUUID);
EuroSession euroSession = (EuroSession) q.getSingleResult();
em.close();
return euroSession;
}
I wonder if there's a way to reset the filter after the first request so it gets the updated session, thank you in advance
I tried calling different times the buscaEuroSession() but didn't changed anything. I can call multiple times the refresh session resource if I turn the filter off, so I'm sure that the problem is there.
Edit: I believe the problem is with EntityManager not getting the last inserted token

How to schedule a java code having messageArrived method of MqttCallback

I am new in MQTT world. I have written a code to subscribe a topic and get message from topic and store it in database. Now my problem is how to put this code on server so that it will keep receiving message infinitely. I am trying to create a scheduler but in that case i am Getting Persistence Already in Use error from MQTT. I cannot change the clientId every time it connect. It is a fixed one in my case. Is there any way to get the persistence object which is already connected for a particular clientId?
Please help. Thanks and advance.
Please Find the code subscribe topic and messageArrived method of mqqt to get message from topic
public class AppTest {
private MqttHandler handler;
public void doApp() {
// Read properties from the conf file
Properties props = MqttUtil.readProperties("MyData/app.conf");
String org = props.getProperty("org");
String id = props.getProperty("appid");
String authmethod = props.getProperty("key");
String authtoken = props.getProperty("token");
// isSSL property
String sslStr = props.getProperty("isSSL");
boolean isSSL = false;
if (sslStr.equals("T")) {
isSSL = true;
}
// Format: a:<orgid>:<app-id>
String clientId = "a:" + org + ":" + id;
String serverHost = org + MqttUtil.SERVER_SUFFIX;
handler = new AppMqttHandler();
handler.connect(serverHost, clientId, authmethod, authtoken, isSSL);
// Subscribe Device Events
// iot-2/type/<type-id>/id/<device-id>/evt/<event-id>/fmt/<format-id>
handler.subscribe("iot-2/type/" + MqttUtil.DEFAULT_DEVICE_TYPE
+ "/id/+/evt/" + MqttUtil.DEFAULT_EVENT_ID + "/fmt/json", 0);
}
/**
* This class implements as the application MqttHandler
*
*/
private class AppMqttHandler extends MqttHandler {
// Pattern to check whether the events comes from a device for an event
Pattern pattern = Pattern.compile("iot-2/type/"
+ MqttUtil.DEFAULT_DEVICE_TYPE + "/id/(.+)/evt/"
+ MqttUtil.DEFAULT_EVENT_ID + "/fmt/json");
DatabaseHelper dbHelper = new DatabaseHelper();
/**
* Once a subscribed message is received
*/
#Override
public void messageArrived(String topic, MqttMessage mqttMessage)
throws Exception {
super.messageArrived(topic, mqttMessage);
Matcher matcher = pattern.matcher(topic);
if (matcher.matches()) {
String payload = new String(mqttMessage.getPayload());
// Parse the payload in Json Format
JSONObject contObj = new JSONObject(payload);
System.out
.println("jsonObject arrived in AppTest : " + contObj);
// Call method to insert data in database
dbHelper.insertIntoDB(contObj);
}
}
}
Code to connect to client
public void connect(String serverHost, String clientId, String authmethod,
String authtoken, boolean isSSL) {
// check if client is already connected
if (!isMqttConnected()) {
String connectionUri = null;
//tcp://<org-id>.messaging.internetofthings.ibmcloud.com:1883
//ssl://<org-id>.messaging.internetofthings.ibmcloud.com:8883
if (isSSL) {
connectionUri = "ssl://" + serverHost + ":" + DEFAULT_SSL_PORT;
} else {
connectionUri = "tcp://" + serverHost + ":" + DEFAULT_TCP_PORT;
}
if (client != null) {
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
client = null;
}
try {
client = new MqttClient(connectionUri, clientId);
} catch (MqttException e) {
e.printStackTrace();
}
client.setCallback(this);
// create MqttConnectOptions and set the clean session flag
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setUserName(authmethod);
options.setPassword(authtoken.toCharArray());
//If SSL is used, do not forget to use TLSv1.2
if (isSSL) {
java.util.Properties sslClientProps = new java.util.Properties();
sslClientProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
options.setSSLProperties(sslClientProps);
}
try {
// connect
client.connect(options);
System.out.println("Connected to " + connectionUri);
} catch (MqttException e) {
e.printStackTrace();
}
}
}

Unrecognized temporary token when attempting to complete authorization: FITBIT4J

I am trying to create a app for fitbit using fitbit4j . I found their sample code
at
https://github.com/apakulov/fitbit4j/blob/master/fitbit4j-example-client/src/main/java/com/fitbit/web/FitbitApiAuthExampleServlet.java
When i tried to implement it I am getting many errors.
below is their doGet function()
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
FitbitAPIClientService<FitbitApiClientAgent> apiClientService = new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(apiBaseUrl, fitbitSiteBaseUrl, credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
);
if (request.getParameter("completeAuthorization") != null) {
String tempTokenReceived = request.getParameter(OAUTH_TOKEN);
String tempTokenVerifier = request.getParameter(OAUTH_VERIFIER);
APIResourceCredentials resourceCredentials = apiClientService.getResourceCredentialsByTempToken(tempTokenReceived);
if (resourceCredentials == null) {
throw new ServletException("Unrecognized temporary token when attempting to complete authorization: " + tempTokenReceived);
}
// Get token credentials only if necessary:
if (!resourceCredentials.isAuthorized()) {
// The verifier is required in the request to get token credentials:
resourceCredentials.setTempTokenVerifier(tempTokenVerifier);
try {
// Get token credentials for user:
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId()));
} catch (FitbitAPIException e) {
throw new ServletException("Unable to finish authorization with Fitbit.", e);
}
}
try {
UserInfo userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
request.setAttribute("userInfo", userInfo);
request.getRequestDispatcher("/fitbitApiAuthExample.jsp").forward(request, response);
} catch (FitbitAPIException e) {
throw new ServletException("Exception during getting user info", e);
}
} else {
try {
response.sendRedirect(apiClientService.getResourceOwnerAuthorizationURL(new LocalUserDetail("-"), exampleBaseUrl + "/fitbitApiAuthExample?completeAuthorization="));
} catch (FitbitAPIException e) {
throw new ServletException("Exception during performing authorization", e);
}
}
}
When i run the code it goes into the 'else' part first and i get the URL with
localhost:8080/fitbitApiAuthExample?completeAuthorization=&oauth_token=5bccadXXXXXXXXXXXXXXXXXXXXXXXXXX&oauth_verifier=h35kXXXXXXXXXXXXXXXXX, and i get the fitbit login screen and when i log in
and since the
'completeAuthorization==null',
it is executing the else part again.So i manually added a value so that it will enter the 'if' section .
So the new URL became
localhost:8080/fitbitApiAuthExample?completeAuthorization=Success&oauth_token=5bccadXXXXXXXXXXXXXXXXXXXXXXXXXX&oauth_verifier=h35kXXXXXXXXXXXXXXXXX and entered the 'if' section.
Now am getting the exception
'Unrecognized temporary token when attempting to complete authorization:'I tried many workarounds but still cant understand the error.
Please Help.
Solved the problem. the 'apiClientService' was going null when i reload the servlet. Made it member variable and everything started working.
public class NewServlet extends HttpServlet {
public String apiBaseUrl = "api.fitbit.com";
public String webBaseUrl = "https://www.fitbit.com";
public String consumerKey = "your key";
public String consumerSecret = "your secret";
public String callbackUrl = "*****/run?Controller=Verifier";
public FitbitAPIClientService<FitbitApiClientAgent> apiClientService = null;
public String oauth_token = null;
public String oauth_verifier = null;
public String token = null;
public String tokenSecret = null;
public String userId = null;
public APIResourceCredentials resourceCredentials=null;
public FitbitApiClientAgent agent =null;
public LocalUserDetail user=null;
public Gson gson =null;
public UserInfo userInfo=null;
private static Properties getParameters(String url) {
Properties params = new Properties();
String query_string = url.substring(url.indexOf('?') + 1);
String[] pairs = query_string.split("&");
for (String pair : pairs) {
String[] kv = pair.split("=");
params.setProperty(kv[0], kv[1]);
}
return params;
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, ParserConfigurationException, SAXException, Exception {
PrintWriter out = response.getWriter();
response.addHeader("Access-Control-Allow-Origin", "*");
// out.println(" ----- process Request Called-----");
String controllerValue = request.getParameter("Controller");
// out.println(" Controller Request : "+param);
if (controllerValue == null) {
// out.println(" inside if part ");
FitbitAPIEntityCache entityCache = new FitbitApiEntityCacheMapImpl();
FitbitApiCredentialsCache credentialsCache = new FitbitApiCredentialsCacheMapImpl();
FitbitApiSubscriptionStorage subscriptionStore = new FitbitApiSubscriptionStorageInMemoryImpl();
FitbitApiClientAgent apiClientAgent = new FitbitApiClientAgent(apiBaseUrl, webBaseUrl, credentialsCache);
out.println("testing2");
apiClientService
= new FitbitAPIClientService<FitbitApiClientAgent>(
apiClientAgent,
consumerKey,
consumerSecret,
credentialsCache,
entityCache,
subscriptionStore
);
// out.println("<script>localStorage.setItem('api',apiClientService);</script>");
LocalUserDetail userDetail = new LocalUserDetail("-");
try {
// out.println("testing4");
String authorizationURL = apiClientService.getResourceOwnerAuthorizationURL(userDetail, callbackUrl);
out.println("access by web browser: " + authorizationURL);
out.println("Your web browser shows redirected URL.");
out.println("Input the redirected URL and push Enter key.");
response.sendRedirect(authorizationURL);
} catch (FitbitAPIException ex) {
out.println("exception : " + ex);
//Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (controllerValue.equalsIgnoreCase("Verifier")) {
oauth_token = request.getParameter("oauth_token");
oauth_verifier = request.getParameter("oauth_verifier");
resourceCredentials = apiClientService.getResourceCredentialsByTempToken(oauth_token);
if (resourceCredentials == null) {
out.println(" resourceCredentials = null ");
throw new Exception("Unrecognized temporary token when attempting to complete authorization: " + oauth_token);
}
if (!resourceCredentials.isAuthorized()) {
resourceCredentials.setTempTokenVerifier(oauth_verifier);
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId()));
}
userId = resourceCredentials.getLocalUserId();
token = resourceCredentials.getAccessToken();
tokenSecret = resourceCredentials.getAccessTokenSecret();
user = new LocalUserDetail(userId);
userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
user = new LocalUserDetail(userId);
agent = apiClientService.getClient();
response.sendRedirect("http://localhost:8084/FitbitClientCheck/");
}

LDAP bind/search in servlet JAVA

I have builded a Java server that listen on a port (6666). Now, i need to connect to this server with a LDAP Browser (I use Softerra). The connection is done, but i have to know when there is an LDAP bind/search, and i have no idea of how to do that.
Here is the code of my server (feel free to tell me if it's not very clear/good, i'm quite new to Java Prog.):
package net.nantes.littleldap;
import java.net.*;
import java.io.*;
public class Serverside {
public static void main(String[] args) {
ServerSocket socketserver ;
Socket socket ;
BufferedReader in;
PrintWriter out;
try {
Authenticate auth = new Authenticate();
socketserver = new ServerSocket(6666);
System.out.println("Le serveur est à l'écoute du port "+socketserver.getLocalPort());
auth.connect();
socket = socketserver.accept();
String inputLine = new String();
in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
System.out.println("Connecté au serveur");
while ((inputLine = in.readLine()) != null){
System.out.println(inputLine);
out = new PrintWriter(socket.getOutputStream());
out.println("Connection réussie");
out.flush();
}
socket.close();
socketserver.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
Sorry, the message are in french, but it's not really important. I think maybe I could do something with InputLine (when I print it, it returns some String relative to LDAP, but i can be hard to parse).
So, any idea ? Thanks a lot !
I would strongly recommend you utilize either JNDI or one of the LDAP SDKs that are available.
We like: https://www.unboundid.com/products/ldap-sdk/
-jim
In addition to listening to the port, your server has to "understand" the LDAP protocol.
I use the OpenDS LDAP SDK (http://www.middleware.vt.edu/pubs/opends-sdk-0.9.0/).
Code is like this
public class MyLdapServer
implements ServerConnectionFactory<LDAPClientContext, Integer> {
private LDAPListener listener;
public void init() {
try {
listener = new LDAPListener(1389, this);
} catch (IOException e) {
logger.error("error opening LDAP listener", e);
}
}
public void destroy() {
listener.close();
}
#Override
public ServerConnection<Integer> handleAccept(LDAPClientContext context)
throws ErrorResultException {
if (logger.isDebugEnabled())
logger.debug("ldap connection from: " + context.getPeerAddress());
IncomingLdapConnection ilc = new IncomingLdapConnection(context);
return ilc;
}
private static Logger logger = LoggerFactory.getLogger(MyLdapServer.class);
}
The IncomingLdapConnection allows you to handle the LDAP operations:
public class IncomingLdapConnection
implements ServerConnection<Integer> {
public void handleBind(Integer ctx, int version, BindRequest request,
ResultHandler<? super BindResult> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException {
if (request.getAuthenticationType() != -128) {
logger.warn("LDAP BIND: unsupported authentication type: " + request.getAuthenticationType());
resultHandler.handleResult(Responses.newBindResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
return;
}
String bindName = request.getName();
if (bindName.length() > 0) {
if (request instanceof GenericBindRequest) {
GenericBindRequest bindRequest = (GenericBindRequest)request;
String userName = parseUidDn(bindName);
if (userName == null) {
// manche LDAP-Clients senden keine DN, sondern direkt den Namen
userName = bindName;
}
String password = bindRequest.getAuthenticationValue().toString();
logger.debug("LDAP BIND: non-anonymous bind, user = " + userName);
anonymous = false;
} else {
logger.warn("LDAP BIND: non-anonymous bind, but unsupported request");
resultHandler.handleResult(Responses.newBindResult(ResultCode.AUTH_METHOD_NOT_SUPPORTED));
return;
}
} else {
logger.debug("LDAP BIND: anonymous bind");
anonymous = true;
}
boolean success = anonymous;
if (!anonymous) {
// authenticate user, set "success"
}
if (success)
resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
else
resultHandler.handleResult(Responses.newBindResult(ResultCode.INVALID_CREDENTIALS));
authenticated = success;
}
EDIT:
OpenDS Code for answering to LDAP search requests
public void handleSearch(Integer ctx, SearchRequest request,
SearchResultHandler responseHandler, IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException {
if (request.getScope() == SearchScope.BASE_OBJECT && request.getName().isRootDN()) {
logger.debug("LDAP Search: BASE_OBJECT");
responseHandler.handleEntry(Responses.newSearchResultEntry(rootEntry));
} else {
// do the search
// parameters: request.getName(), request.getScope(), request.getFilter()
}
responseHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
}
Check out the UnboundID LDAP SDK and some sample code.
EDIT:
I would not recommend the use of JNDI:
JNDI uses a deprecated configuration
JNDI has software defects
JNDI does not fully support LDAP standards
see also
LDAP: Programming Practices

GAE OAuth Java: No authentication header information

I have this error:
WARNING: Authentication error: Unable to respond to any of these challenges: {}
Exception : No authentication header information
I am using GWT with eclipse.
I really don't know what's wrong in my code.
Any help would be appreciated.
Thanks in advance.
Client side EntryPoint class:
private static final String GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
private static final String GOOGLE_CLIENT_ID = "xxxxxxx.apps.googleusercontent.com";
private static final String CONTACTS_SCOPE = "https://www.google.com/m8/feeds";
private static final Auth AUTH = Auth.get();
public void onModuleLoad() {
final AuthRequest req = new AuthRequest(GOOGLE_AUTH_URL, GOOGLE_CLIENT_ID).withScopes(CONTACTS_SCOPE);
AUTH.login(req, new Callback<String, Throwable>() {
public void onSuccess(String token) {
ABASession.setToken(token);
}
public void onFailure(Throwable caught) {
Window.alert("Error:\n" + caught.getMessage());
}
});
}
I store the token in a class that I will use later.
Server side: ContactServiceImpl (RPC GAE procedure)
//The token stored previously is then passed through RPC
public List printAllContacts(String token) {
try {
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey("My consumer key");
oauthParameters.setOAuthConsumerSecret("My consumer secret");
PrivateKey privKey = getPrivateKey("certificate/akyosPrivateKey.key");
OAuthRsaSha1Signer signer = new OAuthRsaSha1Signer(privKey);
ContactsService service = new ContactsService("XXX");
service.setProtocolVersion(ContactsService.Versions.V3);
oauthParameters.setOAuthToken(token);
service.setOAuthCredentials(oauthParameters, signer);
// Request the feed
URL feedUrl = new URL("http://www.google.com/m8/feeds/contacts/default/full?xoauth_requestor_id=xxx.yyy#gmail.com");
ContactFeed resultFeed = service.getFeed(feedUrl, ContactFeed.class);
for (ContactEntry entry : resultFeed.getEntries()) {
for (Email email : entry.getEmailAddresses()) {
contactNames.add(email.getAddress());
}
}
return contactNames;
} catch (Exception e) {
System.err.println("Exception : " + e.getMessage());
}
return null;
}
set the scope
oauthParameters.setScope("http://www.google.com/m8/feeds/contacts/default/full");

Categories

Resources