I'm using facebook4j api (http://facebook4j.org/en/index.html) for access to user data on facebook, so for the login authorization i must provide a acess token, so i found this api: (https://github.com/fernandezpablo85/scribe-java) and from this example (https://github.com/fernandezpablo85/scribe-java/blob/master/src/test/java/org/scribe/examples/FacebookExample.java) i'm trying to get the access token, in the params builder i have to set the callback url:
OAuthService service = new ServiceBuilder()
.provider(FacebookApi.class)
.apiKey(Assets.FACEBOOK_APPID)
.apiSecret(Assets.FACEBOOK_APPSECRET)
.callback()
.build();
But my app is client-side only, so what callback url must i provide?
See here:
redirect_uri. The URL that you want to redirect the person logging in back to. This URL will capture the response from the Login Dialog. If you are using this in a webview within a desktop app, this must be set to https://www.facebook.com/connect/login_success.html.
Related
I am new using Azure Graph Rest API Java using this repo.
My aim is to list all of the users in the AAD tenant
So far I was only able to get to this:
List<String> scopes= Arrays.asList("https://graph.microsoft.com/User.Read.All");
AzureProfile profile = new AzureProfile(tenantId, subscriptionId, AzureEnvironment.AZURE);
final ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
//.httpClient(client)
.authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
.build();
TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(scopes, credential);
GraphServiceClient<Request> graphClient =
GraphServiceClient
.builder()
.authenticationProvider(tokenCredentialAuthProvider)
.buildClient();
UserCollectionPage users = graphClient.users()
.buildRequest()
.get();
for(User user: users.getCurrentPage()){
System.out.println(user.displayName);
System.out.println(user.id);
System.out.println(user.userPrincipalName);
}
However, I run into this error instead:
Caused by: java.io.IOException:
java.util.concurrent.ExecutionException:
com.microsoft.aad.msal4j.MsalServiceException:
AADSTS1002012: The
provided value for scope https://graph.microsoft.com/User.Read.All
openid profile offline_access is not valid. Client credential flows
must have a scope value with /.default suffixed to the resource
identifier (application ID URI).
It seems the Scope that I have used is wrong/insufficient, but I am not too sure what should I use the scope with. Any idea?
It is written in the documentation that:
Client credentials requests in your client service must include
scope={resource}/.default. Here, {resource} is the web API that your
app intends to call, and wishes to obtain an access token for. Issuing
a client credentials request by using individual application
permissions (roles) is not supported. All the app roles (application
permissions) that have been granted for that web API are included in
the returned access token.
The Client Credential flow is best suited for situations where you have a Deamon App that will have to authenticate and get access to some kind of a resource through a Non-Interactive way, which in sequence means that the permissions for this Deamon App have been configured and consented from a step done prior to the auth request.
The /.default scope can be translated as the request of the Background App that runs unattended, to get the bulk of the permissions that it has been configured with and access the resource that it asks.
In plain english, the use of the above scope in the Client Credentials flow is a convention that has to be implemented always when this flow is chosen :P.
I tried to reproduce the same in my environment via Postman and got below results:
I registered one Azure AD application and added API permissions like below:
When I tried to generate access token with same scope as you via Postman using client credentials flow, I got same error as below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
grant_type:client_credentials
client_id: <appID>
client_secret: <secret_value>
scope: https://graph.microsoft.com/User.Read.All openid profile offline_access
Response:
To resolve the above error, you must change your scope to https://graph.microsoft.com/.default if you are using client credentials flow.
After changing the scope, I'm able to generate access token successfully like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
grant_type:client_credentials
client_id: <appID>
client_secret: <secret_value>
scope: https://graph.microsoft.com/.default
Response:
When I used the above token to call below Graph query, I got the list of users with display name, id and user principal name successfully like below:
GET https://graph.microsoft.com/v1.0/users?$select=displayName,id,userPrincipalName
Response:
In your case, change scope value in your code like below:
List<String> scopes= Arrays.asList("https://graph.microsoft.com/.default");
I have a problem with Vertx oauth2.
I followed this tutorial http://vertx.io/docs/vertx-web/java/#_oauth2authhandler_handler:
OAuth2Auth authProvider = OAuth2Auth.create(vertx, OAuth2FlowType.AUTH_CODE, new OAuth2ClientOptions()
.setClientID("CLIENT_ID")
.setClientSecret("CLIENT_SECRET")
.setSite("https://github.com/login")
.setTokenPath("/oauth/access_token")
.setAuthorizationPath("/oauth/authorize"));
// create a oauth2 handler on our domain: "http://localhost:8080"
OAuth2AuthHandler oauth2 = OAuth2AuthHandler.create(authProvider, "http://localhost:8080");
// setup the callback handler for receiving the GitHub callback
oauth2.setupCallback(router.get("/callback"));
// protect everything under /protected
router.route("/protected/*").handler(oauth2);
// mount some handler under the protected zone
router.route("/protected/somepage").handler(rc -> {
rc.response().end("Welcome to the protected resource!");
});
// welcome page
router.get("/").handler(ctx -> {
ctx.response().putHeader("content-type", "text/html").end("Hello<br>Protected by Github");
});
The ideas is to have in the protected folder all the webpages that requires auth.
When I want to access to protected webpage I get redirected to the microsoft login site and after the login I get redirected to my callback.
What I don´t understand is how to handle the callback now?
I get something like this as response:
https://localhost:8080/callback?code=AAABAAA...km1IgAA&session_state=....
How I understood (https://blog.mastykarz.nl/building-applications-office-365-apis-any-platform/) I need to extract somehow the code and the session-state and send back with a post to:
https://login.microsoftonline.com/common/oauth2/token
in order to get the token.
But I did not understand how this can be done with Vertx.
Any help? How to extract the code and session and send back to Microsoft?
I found some tutorials here: https://github.com/vert-x3/vertx-auth/blob/master/vertx-auth-oauth2/src/main/java/examples/AuthOAuth2Examples.java but did not help me.
I am doing this with Azure authentication (in tutorial is written Github but i changed all this to Microsoft).
Are you behind a proxy? The callback handler sends a request to the provider from the application and not from a browser. For me this froze the whole application. You can set the proxy with OAuth2ClientOptions given to the OAuth2Auth.create
As mentioned in the official vert.x-web document, the handling of the auth flow (including access token request to microsoft) is handled by OAuth2AuthHandler:
The OAuth2AuthHandler will setup a proper callback OAuth2 handler so the user does not need to deal with validation of the authority server response.
This being said, there is no need for application to manually handle it. Instead of using example from vertx-auth, try this one instead which actually uses OAuth2AuthHandler.
I am trying to make a Java class which would call upon Google's API to recreate an access token to a user's account with new permissions/larger scope. This class is to be instantiated by a Java servlet I had created. I want a function within that class to return a new access token. For this class to do that, I am using the Scribe library.
In Scribe's quick guide, there are two steps which concern me and have me stumped:
Step Three: Making the user validate your request token
Let’s help your users authorize your app to do the OAuth calls. For
this you need to redirect them to the following URL:
String authUrl = service.getAuthorizationUrl(requestToken);
After this either the user will get a verifier code (if this is an OOB
request) or you’ll receive a redirect from Twitter with the verifier
and the requestToken on it (if you provided a callbackUrl)
Step Four: Get the access Token
Now that you have (somehow) the verifier, you need to exchange your
requestToken and verifier for an accessToken which is the one used to
sign requests.
Verifier v = new Verifier("verifier you got from the user");
Token accessToken = service.getAccessToken(requestToken, v); // the requestToken you had from step 2
It does not seem to specify how to get that verifier from the user. How am I supposed to do that? How do I redirect my user to the authURL, and how do I get it to send its verifier back to this class of mine, which initiated the request to begin with?
If this is unclear, let me structure the question differently, taking Scribe out of the equation: To get an authorization code from Google (which would be used to then get a refresh token and access token), I would execute the following URL connection from within the servlet (yes, I've tried to answer this problem without the Scribe library, and still can't figure it out):
URL authURL = new URL("https://accounts.google.com/o/oauth2/auth");
HttpsURLConnection authCon = (HttpsURLConnection) authURL.openConnection();
authCon.setRequestMethod("GET");
authCon.setDoOutput(false);
authCon.setConnectTimeout(100000);
authCon.setRequestProperty("response_type", "code");
authCon.setRequestProperty("client_id", CLIENT_ID);
authCon.setRequestProperty("redirect_uri",
"http://**************.com/parseAuth/");
authCon.setRequestProperty("scope", convertToCommaDelimited(scopes));
authCon.setRequestProperty("state", csrfSec);
authCon.setRequestProperty("access_type", "offline");
authCon.setRequestProperty("approval_prompt", "auto");
authCon.setRequestProperty("include_granted_scopes", "true");
What has me stuck is what I should be putting for the redirect URI. After getting the user's approval for the new scope, this authorization URL would return an authorization code to the redirect URI, and seemingly nothing to whatever called it. (Am I correct in this?) So if I have another servlet as the redirect URI to parse/extract the authorization code from the response, how in the world do I get that authorization code back to my first, initial servlet? It seems to me that there is no way to have it give back the value to the servlet, in the same position of the code from which the URL was called. It looks like the function has to end there, and all new action must take place within that new servlet. But if that is the case, and I send that auth code to Google's API which would send back a refresh token and access token to ANOTHER servlet I would make to be its redirect URI, how do I possibly get that information back to what it is which called the initial servlet to begin with? That seems to be the same problem at its core, with the problem I am having with Scribe.
I've been stuck on this for many hours, and can't seem to figure out what it is I am supposed to do. I feel like I am missing some key concept, element, or step. I need this clarified. If it is at all relevant, my servlet is hosted on a Jboss application server on OpenShift.
I am implementing twitter in my application using scribe.
After the user authenticate my app and is redirected to new url,
I got the oauth_token and oauth_verifier but could not figure out how to generate oauth_token and oauth_secret from it.
Kindly resolve the issue and thank you in advance!!!
I've solved the problem just make a new service builder(as in the example) in the redirected page and use the oauth_token and oauth_verifier u'll get when u will be redirected to new page like this
Token requestToken = new Token(request.getParameter("oauth_token"),request.getParameter("oauth_verifier"));
Verifier verifier = new Verifier(request.getParameter("oauth_verifier"));
rest is same as in example.
See the Twitter example.
The oauth token and verifier should be what you need to request an access token and access protected resources.
I implemented a Facebook app with Java servlets. I wonder how I can read the access token from the HTTP request sent by Facebook after authentication.
The request sent to me by Facebook looks like this: http://myserver/app/servlet#access_token=3108888%7C2.AQByEGAdEk7D5hs3.3600.130400.1-10005014%7C3XTVE&expires_in=4317
How can I read the access token (which is a fragment and not a parameter) in my Java servlet? If it was a parameter I would do:
request.getParameter("access_token);
To make facebook send the request which contains access_token in http parameters, one needs to change the resoponse_type parameter in request. It is of two types code and token. If we pass token the access_code will be in url fragment and if we pass token it will be request parameter with key as code.
See: Constructing a URL to the OAuth Dialog
For server side handling of access_code e.g. in some servlet, it is needed to send request_type as code else it can be handled only in client side through javascript.