How to configure a Two-legged Spring-OAuth provider/client? - java

Im working on oauth 1 Sparklr and Tonr sample apps and I'm trying to create a two-legged call. Hipoteticly the only thing you're supposed to do is change the Consumer Details Service from (Im ommiting the igoogle consumer info to simplify):
<oauth:consumer-details-service id="consumerDetails">
<oauth:consumer name="Tonr.com" key="tonr-consumer-key" secret="SHHHHH!!!!!!!!!!"
resourceName="Your Photos" resourceDescription="Your photos that you have uploaded to sparklr.com."/>
</oauth:consumer-details-service>
to:
<oauth:consumer-details-service id="consumerDetails">
<oauth:consumer name="Tonr.com" key="tonr-consumer-key" secret="SHHHHH!!!!!!!!!!"
resourceName="Your Photos" resourceDescription="Your photos that you have uploaded to sparklr.com."
requiredToObtainAuthenticatedToken="false" authorities="ROLE_CONSUMER"/>
</oauth:consumer-details-service>
That's adding requiredToObtainAuthenticatedToken and authorities which will cause the consumer to be trusted and therefore all the validation process is skipped.
However I still get the login and confirmation screen from the Sparklr app. The current state of the official documentation is pretty precarious considering that the project is being absorbed by Spring so its filled up with broken links and ambiguous instructions. As far as I've understood, no changes are required on the client code so I'm basically running out of ideas. I have found people actually claiming that Spring-Oauth clients doesn't support 2-legged access (which I found hard to believe)
The only way I have found to do it was by creating my own ConsumerSupport:
private OAuthConsumerSupport createConsumerSupport() {
CoreOAuthConsumerSupport consumerSupport = new CoreOAuthConsumerSupport();
consumerSupport.setStreamHandlerFactory(new DefaultOAuthURLStreamHandlerFactory());
consumerSupport.setProtectedResourceDetailsService(new ProtectedResourceDetailsService() {
public ProtectedResourceDetails loadProtectedResourceDetailsById(
String id) throws IllegalArgumentException {
SignatureSecret secret = new SharedConsumerSecret(
CONSUMER_SECRET);
BaseProtectedResourceDetails result = new BaseProtectedResourceDetails();
result.setConsumerKey(CONSUMER_KEY);
result.setSharedSecret(secret);
result.setSignatureMethod(SIGNATURE_METHOD);
result.setUse10a(true);
result.setRequestTokenURL(SERVER_URL_OAUTH_REQUEST);
result.setAccessTokenURL(SERVER_URL_OAUTH_ACCESS);
return result;
}
});
return consumerSupport;
}
and then reading the protected resource:
consumerSupport.readProtectedResource(url, accessToken, "GET");
Has someone actually managed to make this work without boiler-plate code?

Related

Hyperledger fabric endorsement policy error using Java SDK

I am working on golang version of fabcar smart contract while seeking to implement a Java-SDK API which enrolls an admin, registers a user and performs query-update value operations based on https://github.com/hyperledger/fabric-samples/tree/master/fabcar/java
I have successfully set up a 3 org-9 peers blockchain network, installed, instantiated and invoked chaincode on peers.
However, as i am working on implementing the relative API, i am only able to successfully query blockchain database, while getting a "Could not meet endorsement policy for chaincode mycc"
Please find below screenshot of relative error
Endorsement policy is "OR ('Org1MSP.member','Org2MSP.member', 'Org3MSP.member')".
Should registered user somehow get an Org1/Org2/Org3.member attribute? Any leads would be appreciated!
Like #Ikar Pohorský said, for me this got resolved after I used correct method name. Also, ensure that you delete 'wallet' folder in order to regenerate the user if your HLF n/w was recreated.
#Test
public void testMyMethodToBeInvoked() throws Exception {
deleteDirectory(".\\wallet");
EnrollAdmin.main(null);
RegisterUser.main(null);
// Load a file system based wallet for managing identities.
final Path walletPath = Paths.get("wallet");
final Wallet wallet = Wallet.createFileSystemWallet(walletPath);
// load a CCP
final Path networkConfigPath = Paths
.get("C:\\sw\\hlf146-2\\fabric-samples\\first-network\\connection-org1.yaml");
final Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, "user1").networkConfig(networkConfigPath).discovery(true);
// create a gateway connection
try (Gateway gateway = builder.connect()) {
final Network network = gateway.getNetwork("mychannel");
final Contract contract = network.getContract("mycc");
String myJSONString="{\"a\":\"b\"}";
byte[] result;
// Following did NOT work. Control goes directly to 'invoke' when 'submitTransaction' is done directly. 'invoke' need not be mentioned here.
// result = contract.submitTransaction("invoke", myJSONString);
// Following DID work. In chaincode (my chain code was Java) I had a method named 'myMethodToBeInvoked'. The chain code was written similar to https://github.com/hyperledger/fabric-samples/blob/release-1.4/chaincode/chaincode_example02/java/src/main/java/org/hyperledger/fabric/example/SimpleChaincode.java
result = contract.submitTransaction("myMethodToBeInvoked", my);
System.out.println(new String(result));
}
}
EDIT: Also, please remember that if your chaincode throws errorResponse, even then we can have this endorsement fail issue. So, check if your chain code is working without any issues.

Atlassian Confluence communication/authentication between plugins

I'm (new at this) developing a macro plugin that builds on data that an existing plugin provides via its REST API. They would run on the same instance of Confluence, version 5.9.
I cannot use the Java API of the plugin, since it only provides access to a very limited amount of classes, so I decided on using Rest.
Given that the user has already authenticated with Confluence, is there any way to communicate my current user credentials from my plugins Java Rest client to the other one, preferably not using Basic Authentication?
So far, I've tried:
Shared Access Layer - this apparently used to work with the method Request#addTrustedTokenAuthentication() but is deprecated in SAL 3.0.5,
see SAL Documentation (outdated?), and SAL Version Matrix
ApplicationLink - would allow me to link to another application, but apparently it's not possible to link back to the same Confluence instance
SAL TrustedRequestFactory- comments on this atlassian answer indicate there might be a way using this, but I can't seem to figure it out (yet).
I've also tried reading up on atlassian documentation and posted a similar question on atlassian answers here. I don't mean to double post, but unfortunately, looking at other questions on that platform, few seem to get answered in a timely fashion so I thought I'd try my luck here.
Seems like this isn't a very common problem, but I thought I'd post how we eventually solved this, just in case it's needed again:
#Component
public class RestClient {
#ComponentImport
private TrustedTokenFactory tokenFactory;
// [...]
public String doRequest(HttpClient client, String url) throws Exception {
TrustedTokenAuthenticator auth =
new TrustedTokenAuthenticator(tokenFactory);
HttpMethod method = auth.makeMethod(client, url);
try {
// add request headers, etc...
int statusCode = client.executeMethod(method);
// be sure to use response data here, catch exceptions...
} finally {
method.releaseConnection();
}
}
}

Scope not allowed when calling API Method from API Explorer

I have a strange behaviour in Google App Engine. I am developing with Eclipse and Java, specifically with Google Cloud Endpoints. I created a sample API with the following settings. Actually I was working with many others scopes but I decided to try with only one to track down the error.
#Api(
name = "adminmanagement",
version = "v1",
scopes = {AdminManagement.EMAIL_SCOPE},
clientIds = {AdminManagement.WEB_CLIENT_ID, AdminManagement.API_EXPLORER_CLIENT_ID}
)
public static final String EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
public static final String WEB_CLIENT_ID = "***.apps.googleusercontent.com";
public static final String API_EXPLORER_CLIENT_ID = com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID;
In the API Method as usual I check if the user object is null.
if (user == null) {
throw new OAuthRequestException("Unauthorised Access!");
}
This is pretty much straight forward and it always worked. However this time it does not. If I try to call the API method through the API Explorer I get the following error:
401 Unauthorized
And through the Eclipse Console I can see the following one:
INFO: getCurrentUser: AccessToken; scope not allowed
The SDK version is 1.9.1 but atm I have another application wich uses Drive API and works. I tryed deleting and creating a new Cloud Console, deleting and creating a new App Engine application but I always get this error. By the way, if I deploy the application on App Engine I get a 500 Internal Error with no specification and NOTHING shows up in the logs. Just the API call with no errors whatsover.
This is driving me crazy, what am I missing?
EDIT: The bug DOES NOT occur in version 1.8.9 and below...
The problem magically resolved itself, I haven't changed a thing, however I wasn't the only one with this problem so I supposed Google must have fixed something.

How to handle urn:ietf:wg:oauth:2.0:oob redirect in Google Calendar API Authorization

I am currently working on a installed desktop application implemented in java. I intend to integrate Google Calendar API into the application.
During the authorization procedure, I come to this stage where I am able to get the authorization code only through triggering a browser where the user consent page is displayed. Users then have to click "accept" and will be redirected to a webpage where the authorization code is presented. Users are to copy this code to the Eclipse System.in in order for the authorization process to continue (to exchange the authorization code for a TokenResponse).
My question is that how can I simplify this process so that the user won't have to do this stupid copy-and-paste stuff for the authorization code to be received? (This won't work anyway, if the project is compiled into a jar file...) Currently all I know is that I will need to provide a callbackurl or something, I just can't figure this out. Therefore, I would appreciate a more concrete answer, rather than simply tell me the concepts.
Thanks in advance.
You have to use a service account (which comes with a private key) in order to skip the step involving user interaction. There is a detailed guide about this here.
The oauth2 authorization grant flow (I think, that's what you are doing) defines that your application gets the flow back via a HTTP redirect.
It's like this:
Your application opens a socket and listens there for HTTP requests
It now opens the browser and lets the user enter his/her credentials
The user clicks submit and sends the credentials to the oauth server
The server checks the credentials and, if correct, redirects the browser to your application (to the socket you opened in 1.)
Your application gets the auth code from the browser and exchanges it with the access ticket.
To let the server know where to redirect to, you use the oauth parameter redirect_uri in step 2.
This page seems to indicate that the auth code is in the title of the browser window, and the desktop app is expected to read it from there. (Gack.)
I found the solution.
Note: this is java code, but I bet it works the same way in all other languages.
The problem is my server is very restricted with and so I cannot start either browser there(since that is just a server without UI), either start localhost server for getting the code.
All you need is custom VerificationCodeReceiver:
VerificationCodeReceiver inbrowserListener = new VerificationCodeReceiver() {
#Override
public String getRedirectUri() throws IOException {
return "urn:ietf:wg:oauth:2.0:oob";
}
#Override
public String waitForCode() throws IOException {
// Reading console line
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
#Override
public void stop() throws IOException {
}
};
then simply use it in usual flow:
private static Credential getCredentials() {
.....
return new AuthorizationCodeInstalledApp(flow, inbrowserListener).authorize("user");
}

Cisco JTAPI to CUCM

I have been tasked with writing an application that lets users place calls to Cisco Unified Callmanager 8.6. The contact list will not be provided by the UCM. It will be provided elsewhere.
I find both the documentation and examples provided by Cisco to be lacking and undesirable. I also find the lack of working examples from third parties to be lacking.
My hope is that someone else has done something similar to this before me.
The application gets the numbers to call from a database, it then lets the user click on the contact he or she wants to call. The number of the destination should then be sent to the phone. Basically, in stead of having to dial a number, the application sends the destination to the phone or UCM and the user takes over at this point.
Looking at Cisco's makecall.java, and using it, it seems to be simple to actually place a call using this API.
I have started out by using the example found at http://blog.nominet.org.uk/tech/2008/01/25/experiments-with-jtapi-part-1-making-a-call/ but I believe this piece of code to be insufficient to place a call. I may however be wrong.
Could anyone point me in the right direction here, as I believe my specifications are simple and should be easy to implement. If more information is needed, I will be happy to provide it.
This is months ago, but it still might help you somewhat. I was able to create a test scenario:
protected CiscoJtapiPeer peer;
protected CiscoProvider provider;
// ...
peer = (CiscoJtapiPeer) JtapiPeerFactory.getJtapiPeer(null);
provider = (CiscoProvider) peer.getProvider(cucmURL);
/* cucmURL has the format:
"192.168.0.20;login=myuser;passwd=mypasswd"
whereas the username is an Application User in Cisco Unified Communications
Manager. On my system, it has the following permissions. I don't know whether all
of them are required:
Standard AXL Users
Standard Audit Users
Standard CCM End Users
Standard CCM Phone Administration
Standard CCM Phone and Users Administration
Standard CCM Read Only
Standard CCM Super Users
Standard CTI Allow Call Monitoring
Standard CTI Allow Call Park Monitoring
Standard CTI Allow Control of All Devices
Standard CTI Allow Control of Phone supporting Connected Xfer and...
Standard CTI Enabled
Standard CTI Secure Connection
Standard RealtimeAndTraceCollection
Standard TabSyncUser
You then add an observer to the provider in order to know when the provider
object is read for further interaction. You'll receive a "ProvInServiceEv" Event in the event list.
*/
provider.addObserver(providerObserver);
/* Wait until the event has come up */
// Create a sample call:
CiscoTerminal term = provider.createTerminal("your_sep_id_here");
Call call = provider.createCall();
call.connect(term, term.getAddresses()[0], "your_phone_number_to_call");
term is used as "source" from which the call is started. term.getAddresses()[0] just gets the first phone number associated with the "source" phone. "your_phone_number_to_call" is then called.
Another info: It does not work the other way round: You cannot call provider.getAddress("phonenumber") first, because somehow the phone numbers aren't loaded by the provider class before any terminal is connected to it.
This was tested on a CUCM 8.6.2 and Java 7.
I used this code in my project, works correctly:
final Condition inService = new Condition();
provider.addObserver(new ProviderObserver() {
public void providerChangedEvent(ProvEv[] eventList) {
if (eventList == null) {
return;
}
for (int i = 0; i < eventList.length; ++i) {
if (eventList[i] instanceof ProvInServiceEv) {
inService.set();
}
}
}
});
inService.waitTrue();
Address srcAddr = provider.getAddress(src);
co = new CallObserver() {
public void callChangedEvent(CallEv[] eventList) {
}
};
srcAddr.addCallObserver(co);
call = provider.createCall();
call.connect(srcAddr.getTerminals()[0], srcAddr, dst);
src - phone which you are calling from
dest - phone which you are calling to

Categories