I'm trying to create a user using Googles Directory API and a service account. However I'm getting the error
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://admin.googleapis.com/admin/directory/v1/users?alt=json returned "Not Authorized to access this resource/api". Details: "Not Authorized to access this resource/api">
I've created a service account on the Google Console and allowed Domain wide delegation. It also says the Admin SDK API is enabled for my project. However I can't seem to create a user. The documentation is confusing me slightly. Here is my implementation
def create_googleuser(content, randpass):
''' This function creates a Google Apps account for a user passing webhook contents and password as arguments '''
# Get User info from Webhook and store them in variables
firstname = get_firstname(content)
secondname = get_secondname(content)
emailaddress = firstname + "." + secondname + "#example.com"
# Connect to google API
userscope = ['https://www.googleapis.com/auth/admin.directory.user']
service_account_credentials = ('serviceaccountcredentials.json')
credentials = service_account.Credentials.from_service_account_file(service_account_credentials, scopes=userscope)
userservice = googleapiclient.discovery.build('admin', 'directory_v1', credentials=credentials)
# Create a user dictionary with user details
userinfo = {"primaryEmail": emailaddress,"name":{"givenName":firstname,"familyName":secondname},"password":randpass}
print (emailaddress)
# Create user through googleAPI
userservice.users().insert(body = userinfo).execute()
I'm thinking that my implementation is wrong rather than the permissions as the serviceaccountcredentials.json should have the correct permissions. Any suggestions?
There are two possibilities for getting this error.
If the API method requires an impersonated user to be used.
If the impersonated user has not the relevant service enabled.
Solution for case 1:
Follow the documentation to impersonate a user account.
Solution for case 2:
In the Admin console, open user information and check that the user is not suspended.
Open the "Apps" panel and check that the relevant service is "On".
May be caused by a user not having a license which allows access to the service (Cloud Identity instead of Google Workspace), or a user being in an organizational unit which has the service disabled.
Also this link might be helpful.
Thanks for the input. You were both correct to a point. Basically there were two issues. The service account user needs to be delegated domain administrator privileges that require domain admin actions, domain wide delegation isn't enough. Also the domain scope needed to be broader in the Admin console and the scope definition within the code. There is github issue open which helped here:
https://github.com/googleapis/google-api-nodejs-client/issues/1884
My working code looks like this
def create_googleuser(content, randpass):
''' This function creates a Google Apps account for a user passing webhook contents and password as arguments '''
# Get User info from Webhook and store them in variables
username = get_username(content)
firstname = get_firstname(content)
secondname = get_secondname(content)
emailaddress = firstname + "." + secondname + "#example.com"
# Connect to google API
userscope = ['https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.user.security']
service_account_credentials = ('serviceaccountcredentials.json')
credentials = service_account.Credentials.from_service_account_file(service_account_credentials, scopes=userscope)
delegated_credentials = credentials.with_subject('domain.admin#example.com')
userservice = googleapiclient.discovery.build('admin', 'directory_v1', credentials=delegated_credentials)
# Create a user dictionary with user details
userinfo = {"primaryEmail": emailaddress,"name":{"givenName":firstname,"familyName":secondname},"password":randpass}
# Create user through googleAPI
userservice.users().insert(body = userinfo).execute()
I have configured google provider via cognito user pool and I am able to login through google and get user information. And I have added many attributes on the attribute mapping page as shown in below screenshot.
The endpoint I am using to get user info is https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html.
The response data for user info is always:
data: {
identities: '[{"userId":"xxxx","providerName":"Google","providerType":"Google","issuer":null,"primary":true,"dateCreated":1587772412295}]',
email_verified: 'true',
email: 'xxxx#gmail.com',
username: 'Google_1xxxx'
}
Regardless how I update the attribute mappings, I always see above response. Why can't I get additional attributes like picture, given_name, birthday etc. Do I need to set any permission on google side?
In app client setting, I have below configuration:
In authorized scope, I have set: email openid profile
Im trying to set up WSO2 Identity Server to use OpenId connect. I have currently applied the following settings shown Here: Setup WSO2.
What it boiles down to is that i use the Resident Identity Provider and i have setup a Service Provider for my app "CoolApp".
I configured "OAuth/OpenID Connect Configuration" and set a callback URL.
Is there a simple example how to use this in javascript?
I have played around with identityserver3 and they have a client oidc-client.js which works nicely in combination with identityserver3. However i cant seem to get it working with WSO2 identity server.
I was going about the issue in a wrong way, what i actually wanted was to protect my website using the owin middleware like they tried here and here.
so now i have the following:
app.SetDefaultSignInAsAuthenticationType("ClientCookie");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = "ClientCookie",
CookieName = CookieAuthenticationDefaults.CookiePrefix + "ClientCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(5)
});
// ***************************************************************************
// Approach 1 : ResponseType = "id_token token"
// ***************************************************************************
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
Authority = " https://localhost:9443/oauth2/",
ClientId = "fgx4M5e27NJqgRIs8nu5aL7Jw3oa",
ClientSecret = "dwGdRDCFY7Soa7CB5K5smkiuMmYa",
RedirectUri = "http://localhost:57815/Account/ExternalLoginCallback/",
ResponseType = "id_token token",
Scope = "openid",
Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://localhost:9443/oauth2/authorize",
TokenEndpoint = "https://localhost:9443/oauth2/token",
UserInfoEndpoint = "https://localhost:9443/oauth2/userinfo",
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
var token = n.ProtocolMessage.AccessToken;
// persist access token in cookie
if (!string.IsNullOrEmpty(token))
{
n.AuthenticationTicket.Identity.AddClaim(
new Claim("access_token", token));
}
return Task.FromResult(0);
},
AuthenticationFailed = notification =>
{
if (string.Equals(notification.ProtocolMessage.Error, "access_denied", StringComparison.Ordinal))
{
notification.HandleResponse();
notification.Response.Redirect("/");
}
return Task.FromResult<object>(null);
}
}
});
I put a break point in the SecurityTokenValidated and AuthenticationFailed. Go to the page and i get redirected to the WSO2 identity server as expected. When i login and return to the page both of my break points are NOT hit and im not logged in.
Im using WSO2 Identity Server 5.1.0.
#farasath, could you please help me and the others out looks like we are all running into the same issue and havent found a solution yet.
During further investigation i found out that using the code flow with response_type = "code" will not work either, as the OIDC middleware doesn't support it (see here and here).
Found a suggestion by #pinpoint that ASP.net core does support this. But this is not really an option.
#Hos answered here:
With WSO2 Identity Server 5.0.0 OpenID Connect "id_token" response type is not implemented.
Im not getting the error response he mentioned in his post, but the results for me stay the same using these versions, the breakpoints never get hit. So now i'm wondering should this actually work in 5.1.0 or in the 5.2.0-Beta or is this still WIP.
#farasath, Thank you for your reply here are the logs
[2016-08-16 08:11:39,998] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Validate Client information request for client_id : fgx4M5e27NJqgRIs8nu5aL7Jw3oa and callback_uri http://localhost:57815/
[2016-08-16 08:11:40,074] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Registered App found for the given Client Id : fgx4M5e27NJqgRIs8nu5aL7Jw3oa ,App Name : CoolApp, Callback URL : http://localhost:57815/
[2016-08-16 08:11:50,948] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Authorization Request received for user : raymond#carbon.super, Client ID : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, Authorization Response Type : id_token token, Requested callback URI : http://localhost:57815/, Requested Scope : openid
[2016-08-16 08:11:50,967] INFO {org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration} - The default OAuth token issuer will be used. No custom token generator is set.
[2016-08-16 08:11:50,985] INFO {org.wso2.carbon.identity.oauth2.dao.TokenMgtDAO} - Thread pool size for session persistent consumer : 100
[2016-08-16 08:11:50,991] DEBUG {org.wso2.carbon.identity.oauth2.dao.TokenPersistenceTask} - Access Token context persist consumer is started
... This one repeats about 100 times ...
[2016-08-16 08:11:51,031] DEBUG {org.wso2.carbon.identity.oauth2.authz.AuthorizationHandlerManager} - Successfully created AppInfoCache under OAuthCacheManager
[2016-08-16 08:11:51,206] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Added OAuthAuthzReqMessageContext to threadlocal
[2016-08-16 08:11:52,180] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - No active access token found in cache for Client ID : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, User ID : raymond#carbon.super and Scope : openid
[2016-08-16 08:11:52,199] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - No access token found in database for Client ID : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, User ID : raymond#carbon.super and Scope : openid. Therefore issuing new access token
[2016-08-16 08:11:52,208] DEBUG {org.wso2.carbon.identity.oauth2.dao.TokenPersistenceTask} - Access Token Data persisting Task is started to run
[2016-08-16 08:11:52,208] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - Persisted Access Token for Client ID : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, Authorized User : raymond#carbon.super, Timestamp : 2016-08-16 08:11:52.207, Validity period (s) : 3600, Scope : openid, Callback URL : http://localhost:57815/, Token State : ACTIVE and User Type : APPLICATION_USER
[2016-08-16 08:11:52,233] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - Access Token was added to OAuthCache for cache key : fgx4M5e27NJqgRIs8nu5aL7Jw3oa:raymond#carbon.super:openid
[2016-08-16 08:11:52,298] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Cleared OAuthAuthzReqMessageContext
Second time i ran it i got this log:
[2016-08-16 08:30:17,216] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Validate Client information request for client_id : fgx4M5e27NJqgRIs8nu5aL7Jw3oa and callback_uri http://localhost:57815/
[2016-08-16 08:30:17,222] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Registered App found for the given Client Id : fgx4M5e27NJqgRIs8nu5aL7Jw3oa ,App Name : CoolApp, Callback URL : http://localhost:57815/
[2016-08-16 08:30:23,178] DEBUG {org.wso2.carbon.identity.oauth2.OAuth2Service} - Authorization Request received for user : raymond#carbon.super, Client ID : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, Authorization Response Type : id_token token, Requested callback URI : http://localhost:57815/, Requested Scope : openid
[2016-08-16 08:30:23,189] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Added OAuthAuthzReqMessageContext to threadlocal
[2016-08-16 08:30:23,195] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - Retrieved active Access Token for Client Id : fgx4M5e27NJqgRIs8nu5aL7Jw3oa, User ID :raymond#carbon.super and Scope : openid from cache
[2016-08-16 08:30:23,203] DEBUG {org.wso2.carbon.identity.oauth2.authz.handlers.TokenResponseTypeHandler} - Access Token is valid for another 3264638ms
[2016-08-16 08:30:23,218] DEBUG {org.wso2.carbon.identity.oauth2.util.OAuth2Util} - Cleared OAuthAuthzReqMessageContext
Now i changed my redirect uri to:
RedirectUri = "http://localhost:57815/Account/ExternalLoginCallback/",
and logInfo in that function is always null
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
Googled around and found this post where someone was having similar problems.
Used Fiddler to look at the callback looks like a cookie has been set
So now Im left with the following situation:
Breakpoint in SecurityTokenValidated never hit
Breakpoint in AuthenticationFailed never hit
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); is always null in my Callback
Reason for this is OWIN middle-ware is expecting the OAUTH response in OAUTH 2.0 Form Post Response Mode [1] which is an optional spec and only Identity Server 5.2.0 (With a patch) upwards supports this.
[1] http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html
AFAIK we don't have a Javascript sample that you can use directly. But that shouldn't be a problem at all. I came across [1] by simply googling. All you need to do is to replace the client_id and callback URL. Since we follow the OAuth/OpenID connect spec any OAuth Javascript client library should work with WSO2 Identity Server.
We do have a web app sample[2] and I wrote a blog post[3] earlier just to demonstrate the authorization code flow with WSO2 Identity Server.
[1] https://github.com/zalando/oauth2-client-js
[2] https://docs.wso2.com/display/IS510/OAuth+2.0+with+WSO2+Playground
[3] http://blog.farazath.com/2016/05/trying-out-oauth2-authorization-code.html
We have a website integrated with ADFS 3 for authentication. Website allows users to change their usernames, which in turn changes their usernames in AD. If users changes their usernames we log them out using WSFederationAuthenticationModule.FederatedSignOut. However the page redirects to adfs url and throws an error. The event log shows that "either username or password is wrong".
MSIS7066: Authentication failed for the request. ---> System.Security.SecurityException: The user name or password is incorrect.
I wonder it is because of user name change. I tried with both lsalookupcachemaxsize set to 0 in registry and without the key. By the way does ADFS 3 even consider this registry key?
The code used is below -
FormsAuthentication.SignOut();
FederatedAuthentication.SessionAuthenticationModule.SignOut();
FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
FederatedAuthentication.WSFederationAuthenticationModule.SignOut(false);
Response.Expires = 0;
Session.Abandon();
var authenticationModule = FederatedAuthentication.WSFederationAuthenticationModule;
WSFederationAuthenticationModule.FederatedSignOut(new Uri(authenticationModule.Issuer), new Uri(authenticationModule.Realm));
I'm doing an agent SAML2.0 SSO using the code that is in this url:
http://svn.wso2.org/repos/wso2/people/asela/wso2-samples/sso_webapp/
but it does not work the logout. Excuse my English.
I am told, when the identity server sends responses of the authentication, sends a session index value in it and you need to return exactly the same value in the logout request to the identity server. How I can get the index value of the session with SAML 2.0?
This is the code of my class LogoutRequestBuilder
public LogoutRequest buildLogoutRequest(String subject, String reason) {
Util.doBootstrap();
LogoutRequest logoutReq = new org.opensaml.saml2.core.impl.LogoutRequestBuilder().buildObject();
logoutReq.setID(Util.createID());
DateTime issueInstant = new DateTime();
logoutReq.setIssueInstant(issueInstant);
logoutReq.setNotOnOrAfter(new DateTime(issueInstant.getMillis() + 5 * 60 * 1000));
IssuerBuilder issuerBuilder = new IssuerBuilder();
Issuer issuer = issuerBuilder.buildObject();
issuer.setValue(Util.getProperty(SSOConstants.ISSUER_ID));
logoutReq.setIssuer(issuer);
NameID nameId = new NameIDBuilder().buildObject();
nameId.setFormat(SSOConstants.SAML_NAME_ID_POLICY);
nameId.setValue(subject);
logoutReq.setNameID(nameId);
SessionIndex sessionIndex = new SessionIndexBuilder().buildObject();
sessionIndex.setSessionIndex(Util.createID());
logoutReq.getSessionIndexes().add(sessionIndex);
logoutReq.setReason(reason);
return logoutReq;
}
}
If single logout is enabled in service provider registration in WSO2IS. Within the SAML response you get will contain the SessionIndex.
So that value has to be stored somewhere to send back in the logout request.
This is an old sample you are using. [1] This document contain the sso sample which has single log out enabled.
[1] https://docs.wso2.com/display/IS500/Configuring+SAML2+SSO