GoogleConntectionFactory can't create connection - spring

G'day everybody!
I've got error like this:
WARN/DefaultRequestDirector(22739): Authentication error: Unable to respond to any of
these challenges: {authsub=WWW-Authenticate: AuthSub
realm="https://www.google.com/accounts/AuthSubRequest" allowed-
scopes="https://www.googleapis.com/auth/userinfo.email,
https://www.googleapis.com/auth/userinfo.profile,
https://www.googleapis.com/auth/userinfo.id"}
It's happend when I wanna get connection:
AccessGrant accessGrant = new AccessGrant(accessToken);
Connection<Google> connection = connectionFactory.createConnection(accessGrant);
As the result, I catch exception as Auth 401.
Did any one that problem befor?

It looks like you are using the old AuthSub authentication when you should be using OAuth2 authentication. I suggest you take a look at the example application, specifically see in SocialConfig how to create ProviderSignInController which is used for sign in.

I've found why it was happened. The problem was in scope. I set only https://www.googleapis.com/auth/plus.me scope. It wasn't enough for create connection.
As result, I had the next message:
WARN/DefaultRequestDirector(22739): Authentication error: Unable to respond to any of
these challenges: {authsub=WWW-Authenticate: AuthSub
realm="https://www.google.com/accounts/AuthSubRequest" allowed-
scopes="https://www.googleapis.com/auth/userinfo.email,
https://www.googleapis.com/auth/userinfo.profile,
https://www.googleapis.com/auth/userinfo.id"}
As you can see google oauth2 asks for https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile, https://www.googleapis.com/auth/userinfo.id scopes.
After I had added this scopes and I got a new error likes "invalid_scope".
Problem was in connection url.
I created connection url as:
connectionFactory.getOAuthOperations().buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, params);
where params:
OAuth2Parameters params = new OAuth2Parameters();
params.setRedirectUri(redirectUri);
params.setScope("https://www.googleapis.com/auth/userinfo.email+" + "https://www.googleapis.com/auth/userinfo.profile+" + "https://www.googleapis.com/auth/userinfo.id+" +
"https://www.googleapis.com/auth/plus.me");
In this case, symbol "+" was decoded to another one and Google oauth2 api couldn't recognize scope set.
I hope this solution will help somebody in future.

Related

Django-allauth + reactjs+ linkedin login redirect uri issue + Not enough permissions to access: GET /me

I am using drf + ReactJs to do social login am able to integrate google login and facebook login using django allauth package , but when I tried to integrate linkedin login getting error :
invalid redirect uri
TO be more precise am getting this error
allauth.socialaccount.providers.oauth2.client.OAuth2Error: Error retrieving access token: b'{"error":"invalid_redirect_uri","error_description":"Unable to retrieve access token: appid/redirect uri/code verifier does not match authorization code. Or authorization code expired. Or external member binding exists"}
----few updates after tying out few fixes -----
Tried fetching the access token from backend and login the user using a seprate api it showed the redirect uri issue.
Tried directly calling the linkedin token url from postman and now I get Invalid request error.
First method worked after few tryouts but now getting incorrect value error.
Tried fetching code with scope as r_liteprofile but now getting 403 forbidden
{'serviceErrorCode': 100, 'message': 'Not enough permissions to access: GET /me', 'status': 403}
I tried changing url to backend and frontend both showing same error. Can anyone get me how to fix this issue ?
I am not sure what all additional details needed for sorting this out, Please let me know if any needed.
Finally able to find the solution
the issue was with the code generated from the sdk used to implement linkedin login in reactjs, which has only scope
r_emailaddress
r_liteprofile
Adding additional scope
w_member_social
And regarding redirect uri issue
we are suppose to use the same redirect uri in both frontend and backend
made things working , posting this here since it will help someone in future facing same problem.
thank you all

Spring Keycloak adapter Permissions Policy Enforcer. How to set it up

First of all I'm using
keycloak-authz-client-3.3.0.Final
spring boot 1.5.8.RELEASE
spring-boot-starter-security
I've been playing with Keycloak spring adapter exploring the examples since we want to adopt it to our project.
I was able to make it run for Roles easily using this tutorial:
https://dzone.com/articles/easily-secure-your-spring-boot-applications-with-k
After that I moved to permissions and that's when it gets trickier (that's also our main goal).
I want to achieve something like described in here (9.1.2):
http://www.keycloak.org/docs/2.4/authorization_services_guide/topics/enforcer/authorization-context.html#
To get permissions you need to setup in Keycloak Authorization, credentials, and then create Resources or Scopes and Policies to be able to create permissions (it took me a while but I got it working). Testing in the Evaluater everything seems fine.
Next step was to get user permissions on the Spring side. In order to do that I had to enable:
keycloak.policy-enforcer-config.enforcement-mode=permissive
The moment I enable this I get everytime this exception
java.lang.RuntimeException: Could not find resource.
at org.keycloak.authorization.client.resource.ProtectedResource.findAll(ProtectedResource.java:88)
at org.keycloak.adapters.authorization.PolicyEnforcer.configureAllPathsForResourceServer...
...
Caused by: org.keycloak.authorization.client.util.HttpResponseException:
Unexpected response from server: 403 / Forbidden
No matter what address I hit in the server.
So I started to investigate what was the root of the problem. Looking at some examples how to manually get the permissions I actually got them in postman with the following request:
http://localhost:8080/auth/realms/${myKeycloakRealm}/authz/entitlement/${MyKeycloakClient}
including the header Authorization : bearer ${accessToken}
response was {"rpt": ${jwt token}} that actually contains the permissions
So knowing this was working it must be something wrong with the Spring adapter. Investigating a bit further on the Keycloak exception I found that that error was occurring the moment the adapter was getting all the resources. For that it was using the following url:
http://localhost:28080/auth/realms/license/authz/protection/resource_set
with a different token in the headers (that I copied when debugging)
So when I tried it in postman I also got a 403 error, but with a json body:
{
"error": "invalid_scope",
"error_description": "Requires uma_protection scope."
}
I've enabled and disabled all uma configuration within keycloak and I can't make it work. Can please someone point me into the right direction?
Update
I've now updated Keycloak adapter to 3.4.0.final and I'm getting the following error in the UI:
Mon Nov 20 10:09:21 GMT 2017
There was an unexpected error (type=Internal Server Error, status=500).
Could not find resource. Server message: {"error":"invalid_scope","error_description":"Requires uma_protection scope."}
(Pretty much the same I was getting in the postman request)
I've also printed all the user roles to make sure the uma_protection role is there, and it is.
Another thing I did was to disable spring security role prefix to make sure it wasn't a mismatch on the role.
Update 2
Was able to resolve the 403 issue (you can see it in the response below).
Still getting problems obtaining KeycloakSecurityContext from the HttpServletRequest
Update 3
Was able to get KeycloakSecurityContext like this:
Principal principal = servletRequest.getUserPrincipal();
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) principal;
OidcKeycloakAccount auth = token.getAccount();
KeycloakSecurityContext keycloakSecurityContext = auth.getKeycloakSecurityContext();
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
The problem now is that the AuthorizationContext is always null.
I've managed to get it working by adding uma_protection role to the Service Account Roles tab in Keycloak client configuration
More information about it here:
http://www.keycloak.org/docs/2.0/authorization_services_guide/topics/service/protection/whatis-obtain-pat.html
Second part of the solution:
It's mandatory to have the security constrains in place even if they don't mean much to you. Example:
keycloak.securityConstraints[0].authRoles[0] = ROLE1
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /*
Useful demos:
https://github.com/keycloak/keycloak-quickstarts
This code works for me:
HttpServletRequest request = ...; // obtain javax.servlet.http.HttpServletRequest
Principal userPrincipal = request.getUserPrincipal();
KeycloakPrincipal < KeycloakSecurityContext > keycloakPrincipal =
(KeycloakPrincipal < KeycloakSecurityContext > ) userPrincipal;
KeycloakSecurityContext securityContext =
keycloakPrincipal.getKeycloakSecurityContext();
If you faced "java.lang.RuntimeException: Could not find resource" error and you are using Keycloak docker container, The error can be because of this. I dont have enough information about docker. Hence I download keycloak as a zip file and run it. It works properly.

OAuth token parameter missing when using request_youtube API

I try to using youtube API in code ingniter and using librari from https://github.com/jimdoescode/CodeIgniter-YouTube-API-Library when i call request_youtube()from direct link the https://accounts.google.com/o/oauth1/auth sent massage like this :
400. That’s an error.
OAuth token parameter missing.
That’s all we know.
This the code of request_youtube() :
public function request_youtube()
{
$params['key'] = xxxxxxxxxxxx.apps.googleusercontent.com';
$params['secret'] = 'xxxxxxxxxxxx';
$params['algorithm'] = 'HMAC-SHA1';
$this->load->library('google_oauth', $params);
$data = $this->google_oauth->get_request_token(base_url().'index.php/example/access_youtube');
$this->session->set_userdata('token_secret', $data['token_secret']);
redirect($data['redirect']);
}
what wrong with my code...or any step i miss???
The library that you are using is deprecated probably because of which it is unable to make calls to the Google Servers and is returning 404 errors. You can still follow the original way of authentication using OAuth where you validate your app with the client id client secret and get the Auth code. With the Auth code making a POST request and getting a access token and a refresh token in exchange. For details please refer to this official Google Youtube Documentation on OAuth.

Invalid grant when accessing Google API

I'm trying to invoke any of the Google API using "Service account" authorization access. I have downloaded ".pk2" file and activated "URL Shortener API" in Services tab of Google API console. Whenever I try to invoke any API (URL shortener or Adsense). I've got following exception -
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323)
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:345)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:526)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:287)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:836)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:412)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:345)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:463)
Below is code snippet -
HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
JsonFactory JSON_FACTORY = new JacksonFactory();
File privateKey = new File(ReportAdsense.class.getResource("mykey.p12").toURI());
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("my_valid_account_id#developer.gserviceaccount.com")
.setServiceAccountScopes(UrlshortenerScopes.URLSHORTENER)
.setServiceAccountPrivateKeyFromP12File(privateKey)
.build();
Urlshortener service = new Urlshortener.Builder(new NetHttpTransport(), JSON_FACTORY, null).setHttpRequestInitializer(credential).build();
UrlHistory history = service.url().list().execute();
First of all "Service account" will not work for Adsense, since it requires user authorization. Hence for Adsense you should use Oauth 2.0. When you are authorized first time using URL https://accounts.google.com/o/oauth2/token, copy-paste and hardcode your refresh token. Than you can use it to get access token, specify client_id, client_secret and your refresh_token to get new access token. Now access token can be used in your application.
Regarding your error, I have faced with similar issue and spent plenty of time to resolve it. First of all, make sure that you are using valid ServiceAccountId - it should point to email which finishes with "developer.gserviceaccount.com". Make sure, that you specified account scopes and activated services in Google Console API.
I fixed this issue by synchronizing system clock in my machine.
There are a lot of topics with similar error without answers. Even more, some people says, that sometimes it works, sometimes it returns invalid grant. It could work on one machine and fail on another. I don't know if it is system clock issue, but I would avoid using Service Account API, since looks like there are bugs and support would not help you

gdata SetAuthenticationToken() - 403 forbidden

I am just trying to get list of Albums in a web app using following c# code.
For AccessToken, I wen to OAuthPlaygound and generated an accessToken
with Picasa in scope using valid consumer key and password which relevant to my web application.
Issue :When I execute following code, I get 403 forbidden error along with message as "Invalid Token" error on last line if I use SetAuthenticationToken() option.
However, if I use setUserCredentialss(), it works. Could anyone please
help me in this? Is it that token generated using OAuth Playground
doesn't work here? Or to use client library token should also be geenrated using it? Is there any workaround?
PicasaService service = new PicasaService("codesamples.google.com");
service.SetAuthenticationToken(accessToken); //Doesn't works
//service.setUserCredentials("myUsername", "myPassword"); //Works
AlbumQuery query = new AlbumQuery(PicasaQuery.CreatePicasaUri(username));
PicasaFeed feed = service.Query(query);

Resources