How do I generate a Dart client library for my Google Cloud Endpoints API using discoveryapis_generator? - dart

I have an endpoints API that I'm accessing with a Dart client library generated with discoveryapis_generator. All is well and good except that the generated library doesn't appear to reflect the authentication requirements of my API.
Is it only necessary to somehow create an authenticated http object to pass to my application's BrowserClient() constructor in the following line?
my_api = new MyApi(new BrowserClient());
Is the recommended method for creating the authenticated http object to use the googleapis_auth package as described here? Am I on the right track?

The authentication is not part of the API itself. It is actually the http client that will send the proper http header for user authentication. Assuming you use the standard google auth mechanism, you can use the package https://pub.dartlang.org/packages/googleapis_auth as you would for a standard Google API (Drive, etc...).
You will have to create a clientId (google console) and use BrowserOAuth2Flow to get an AuthClient (that extends http.client) and from then do new MyApi(authClient)
I have a (quite old) project where I override the standard behavior of google auth to allow specifying a userId (never really found the doc on that but it works) during authentication with a simple example that use the PlusApi to get the user name but it could work in a similar way for your own api. Maybe that could help https://github.com/alextekartik/tekartik_googleapis_auth.dart
I think you need at least the email scope when calling createImplicitBrowserFlow
There are also samples for using google apis that could help: https://github.com/dart-lang/googleapis_examples

Related

How to implement custom 'OAuth2TokenIntrospectionEndpointFilter' in Spring Aauthorization server 1.0.0?

I have a default Spring authorization Server implementation. i want to modify it as per my project requirements.
I want to implement customized introspection endpoint in new spring authorization server.
I will be having different kinds of tokens, based on token type I want to validate them differently.
So I found out by default spring authorization server uses 'OAuth2TokenIntrospectionEndpointFilter', is there a way to use this class or we have to write a new class and add it to server configuration?
Thank you.
I tried doing the following.
authorizationServerConfigurer.tokenIntrospectionEndpoint(
t -> t.authenticationProvider(customTokenAuthProvider)
.introspectionResponseHandler(successHandler));
I want to know if this the right way to do or any other method exists.
It seems you have two goals:
Customize a jwt, by adding custom claims.
Obtain those claims via the introspection endpoint from a resource server.
There is actually nothing to code for on the authorization server side to achieve #2, as the introspection endpoint returns all claims for a jwt by default. I’m not clear on what you mean by “validate” here, so I’m assuming you mean validate the token and then obtain claims from it. This is what the introspection endpoint does, no customization required. Do note however that the introspection endpoint is not usually called if the resource server is decoding the jwt locally. This would only happen if the resource server is treating the token as opaque.
In order to achieve #1, simply provide an OAuth2TokenCustomizer #Bean as demonstrated in the reference documentation.
Note: I don’t see a need for a custom AuthenticationProvider. If you feel you do have a need for one, then I think some details of your use case are missing.

How to manage API side authorization for Google?

I'm responsible for the API side of our product. We have several different clients, from browsers to iPads to Chromebooks. Right now, all our authentication is done directly from the client to our API, with username & password.
I've inherited some code that does authentication using OAuth, with the usual username/password setup. So inside my OwinAuthConfig class, I have:
var oAuthAuthorizationOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Authenticate"),
Provider = new MyAuthorizationProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
app.UseOAuthAuthorizationServer(oAuthAuthorizationOptions);
Then, through some dark magic, this connects up with my MyAuthorizationProvider class (which inherits OAuthAuthorizationServerProvider), and on login, this invokes the method:
public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{ ... }
where context contains the important stuff (Username and Password) which I can then use to authenticate the user, build his claims, create an AuthenticationTicket and this information then magically gets returned to the client with the access token etc.
All well and good.
Now I have a new requirement - to allow 3rd party authentication from Google. In this case, the client app (iOS/Android/whatever) does the authentication with Google, and they should just pass the token (and any other required info) to me on the API side. On my side I then need to re-authenticate the Google token, and get all the user info from Google (email, name, etc.), from which I should then again link that to our User table, build up the claims etc. and return a new token to the client, which will be used in all subsequent calls.
Being kinda new to the whole OWIN pipeline thing, I'm not sure exactly how to go about this. I could write a new GoogleAuthController, that just acts like any other controller, and have an API that accepts the Google token, and returns the new token and other info in the same format that the username/password authentication API does it. But 2 things are nagging at me:
I have this awkward feeling like this is the noobie way of doing things, reinventing the wheel, and really there's a super-cool magical way of hooking things together that I should rather be using; and
In MyAuthorizationProvider.GrantResourceOwnerCredentials(), I've got access to an OAuthGrantResourceOwnerCredentialsContext object, which allows me to validate my new AuthenticationTicket. If I'm doing this inside a plain vanilla controller, I have no idea how I would mark that ticket as validated.
Any clues, please?
EDIT I've seen the Google auth flow as described here. I'm still confused by how best to manage the process from the API side. The client will be obtaining the authorization code, and then calling the API with that auth code. I get that then I've got to take that auth code and convert it to a token by calling the Google API. (Or maybe that should be the client's responsibility?) Either way, I then need to use that token to go back to the Google API and get the user's name, email and avatar image, then I need to match up that email with my own database to identify the user and build up their claims. Then I need to return a new token that the client can use to connect to me going forward.
Let me be more specific about my questions, before my question is closed as "too broad":
When the client has completed authentication with the Google API, it gets back a "code". That code still needs to be converted into a token. Whose responsibility should that be - the client or the API? (I'm leaning towards making it the client's responsibility, if just for the reason of distributing the workload better.)
Whether the client is passing through a code or a token, I need to be able to receive it in the API. Should I just use a plain vanilla Controller to receive it, with an endpoint returning an object of type AuthenticationProperties, or is there some special OWIN way of doing this?
If I'm using a plain vanilla Controller, how do I validate my token? In other words, how do I get access to the OWIN context so that I can mark the AuthenticationTicket as validated?
How do I write an automated test that simulates the client side of the process? AFAICT, the authentication wants to have a user physically click on the "Allow" button to grant my app access to their identity stuff, before it will generate the auth code. In an automated test, I would want to pass username/password etc. all from code. How do you do that?
So I found a solution of my own. It's only slightly kludgy, doesn't require referencing any Google OWIN libraries, and best of all, reuses the code from my username/password authentication.
Firstly, I get the app to call the same Authenticate endpoint as I do for username/password, only with dummy credentials, and add in a "GoogleToken" header, containing the token.
In my authentication code, I check for the GoogleToken header, and if it exists, follow that code path to validate on the Google servers, get an email address, and link to my own User table. Then the rest of the process for building claims and returning a new API token follows the original path.
start here : https://developers.google.com/identity/protocols/OAuth2#basicsteps
This explains how oAuth2 works. So you receive a Google token, now you call Google and request the user's details. you will receive their email which is enough to authenticate them. You could store the token as they are valid for a while and you can keep reusing it for whatever you need until it expires or it is invalidated.
Check this discussion on the same subject :
How can I verify a Google authentication API access token?
if you need more info on how OAuth2 works I can point you to one of my own articles : https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/
There's a lot to take in, but it sounds like you need to understand how these things work together. Hope this helps.
Update:
I don't have full access to your setup, but I hope that the following code might help you with using Google as ID provider. Please add the following code to your startup.auth.cs file.
var googleAuthOptions = new GoogleOAuth2AuthenticationOptions
{
ClientId = "ef4ob24ttbgmt2o8eikgg.apps.googleusercontent.com",
ClientSecret = "DAK0qzDasdfasasdfsadwerhNjb-",
Scope = { "openid", "profile", "email" },
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = async ctx =>
{
//You can get the claims like this and add them to authentication
var tokenClaim = new Claim("GoogleAccessToken", ctx.AccessToken);
var emailClaim = new Claim("email", ctx.Email);
var claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddClaim(tokenClaim);
claimsIdentity.AddClaim(emailClaim);
HttpContext.Current
.GetOwinContext()
.Authentication
.SignIn(claimsIdentity);
await Task.CompletedTask;
}
},
AuthenticationType = "Google"
};
app.UseGoogleAuthentication(googleAuthOptions);
This allows the Google to act as ID Provider and the OnAuthenticated gets called when the authentication is successful. You can get the claims out of it and use them to signin. Please let me know if this worked, if not give me more details about your setup (what kind of framework, client setup and may be more details about your setup in startup file).
Thank you.
Please see this link for details on how we can use Google as ID Provider. I am sure you might have looked at this link, but in case you missed it. If none of these links work for you please include specific details on where you are deviating from what is mentioned in the links.
I assume you have a different requirement than what is specified in those links. Hence, I will try to answer your questions individually. Please let me know if you have any further questions.
When the client has completed authentication with the Google API, it gets back a "code". That code still needs to be converted into a token. Whose responsibility should that be - the client or the API? (I'm leaning towards making it the client's responsibility, if just for the reason of distributing the workload better.)
Exchanging the code for access token is definitely the responsibility of the API as the token exchange involves sending the ClientId and Client Secret along with the code. Client secret is supposed to be saved on the server side (API) but not on the client
Whether the client is passing through a code or a token, I need to be able to receive it in the API. Should I just use a plain vanilla Controller to receive it, with an endpoint returning an object of type AuthenticationProperties, or is there some special OWIN way of doing this?
This should work seamlessly if you are using the Google provider as mentioned in the above links. If not, the endpoint should be an anonymous endpoint accepting the code and making a request to Google (may be by using HttpClient) to get the access token along with the profile object for user related information.
If I'm using a plain vanilla Controller, how do I validate my token? In other words, how do I get access to the OWIN context so that I can mark the AuthenticationTicket as validated?
You have to implement OnGrantAuthorizationCode as part of your MyAuthorizationProvider class. This gives access to the context to set validated to true.
How do I write an automated test that simulates the client side of the process? AFAICT, the authentication wants to have a user physically click on the "Allow" button to grant my app access to their identity stuff, before it will generate the auth code. In an automated test, I would want to pass username/password etc. all from code. How do you do that?
This can be achieved partially, but, with that partial test you can be sure of good test coverage against your code. So, you have to mock the call to the Google API and assume that you have retrieved a valid response (hard code the response you received from a valid manual test). Now test your code on how it behaves with the valid response. Mock the Google API cal for an invalid response and do the same. This is how we are testing our API now. This assumes that Google API is working fine and tests my code for both valid/ in-valid responses.
Thank you,
Soma.
Having gone through something like this recently, I'll try to answer at least some of your questions:
The client should be getting a token from Google, which you can pass unaltered through to the API:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var idToken = googleUser.getAuthResponse().id_token;
}
A plain vanilla Controller should do it. The client can subsequently post an object in there, containing at least that token plus the client id (might be useful to know where the request comes from) and even the providerUserId;
Unfortunately I'm not that familiar with the Owin stack
Fully end-to-end integration testing might be tricky, although you might achieve something through tools like Selenium, or some mocking tool. The API however should be testable just by posting some fake data to that vanilla controller, although you might have to rely on some sort of mock implementation when you get to validating that token through Google (although you could also validate it manually on the server, provided you get the Google public api key).

Need to generate/validate OAuth tokens in ASP.NET 5

I have built an API in C# ASP.NET 5.
This is current the code library I use to generate and validate OAUTH tokens https://github.com/mrsheepuk/ASPNETSelfCreatedTokenAuthExample
The logged in user calls my API (passing the Bearer token in the header) to retrieve their saved notes from my NoteController. In my NoteController I retrieve the userNo from the Auth token claims and retrieve the users notes from the database. If the user's Auth token is invalid then I send them back a HTTP 401.
I have added code in my Startup.cs to enable Authorization:
// Enable the use of an [Authorize("Bearer")] attribute on methods and classes to protect.
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
.RequireAuthenticatedUser().Build());
});
My problem: as good as the code library (ASPNETSelfCreatedTokenAuthExample) is, it does not provide an OAuth refresh token mechanism.
I have tried to find a decent library to replace the one I am currently using.
I want a library that uses refresh tokens etc.
I have looked at IdentityServer4 but the examples are just for generating tokens in a dedicated server
I don't quite understand what to do :(
Can someone point me in the right direction please?
Thanks
DONE IT!!! :D
found this amazing blog post
http://capesean.co.za/blog/asp-net-5-jwt-tokens/
It took me a few mins to get his source code to work.
I actually had to use someone's fork of the solution to get it to work
https://github.com/VoronFX/openiddict-test
My steps to get it to work:
1. Download https://github.com/VoronFX/openiddict-test
Next steps are copied from (https://github.com/openiddict/openiddict-core)
run these commands:
set DNX_UNSTABLE_FEED=https://www.myget.org/F/aspnetcidev/
dnvm upgrade -u
Update your project.json to import the OpenIddict package:
"dependencies": {
"OpenIddict": "1.0.0-*"
},
Direction -> If I would have such a task, probably I would get familiar with the official AspNetCore middleware and try to implement my own middleware based on the official OAuth middleware. Have a look here -> https://github.com/aspnet/Security/tree/dev/src/Microsoft.AspNetCore.Authentication.OAuth.
More authentication middlewares: https://github.com/aspnet/Security

WWW-Authenticate schemes for OpenID Connect

I'm writing my own codes for the OpenID Connect protocol. Basically, I intend to write my own provider and related stuff on Google App Engine's platform using Jersey and Google's datastore via Objectify library.
I'm in the middle of implementing the (access/refresh) token endpoint and there's this client authentication that I need to take care of. I'm just wondering if there are preset authentication schemes' keywords that I could send if in case the client did not have client_secret_basic set during the registration process (or whatever's set in the datastore entry.)
For a failed client authentication with the following methods, the scheme is used as response in the WWW-Authenticate header (401):
client_secret_basic: Basic,
client_secret_post: ???,
client_secret_jwt: ???,
private_key_jwt: ???,
none: obviously none.
I've looked at some open source implementations, nimbus' and OAuth-Apis', but they don't seem to handle this minor issue (they only respond with the generic error response defined in OAuth2 rfc6749#section-5.2.)
If there are no predefined keywords, then I suppose I'll have to make up my own. But it would be great if they exist.
The authoritative list for these is at IANA. There, you can find these handfuls:
Basic
Bearer
Digest
HOBA
Mutual
Negotiate
OAuth
SCRAM-SHA1
SCRAM-SHA-256
vapid
Which of these is client_secret_post, client_secret_jwt and private_key_jwt? None. You'll need to map those to one from the registered list above or return your own values. Better yet, you can submit a draft to the OAuth working group or the OpenID Foundation to get the above IANA registry updated with something that makes sense for these missing cases. Then, we can all interop :-)

How to check for oAuth2 scopes in Apigility?

I am creating an apigility project where we will be hosting all of our APIs. We need to be able to use OAuth2 for authentication but we cannot figure out how to control access to certain APIs, it seems like once a client authenticates, they can use any of our APIs but we want to limit them to use only specific ones that we define. After reading about the OAuth2 library that apigility uses, I saw that there are scopes that can be defined but I have not found any documentation about how to check a user's scope to see if they have access. I want to find out if this is the best way to restrict access to certain APIs and how to set it up if it is, or is there a better way to control access?
Just implemented this functionality using the following recipe ...
https://github.com/remiq/apigility-zfc-rbac-recipe
It worked really well and only took a few hours to get it all working.
Alternatively you can just do the checking in the Controller Action (Resource method)
$identity = $this->getIdentity()->getAuthenticationIdentity();
$scope = $identity["scope"]
if (! in_array('admin', $scope)) {
return new ApiProblem(Response::STATUS_CODE_401, 'No Auth');
}
The above code is untested but should get you on the right path if you wanted to do it that way

Resources