Currently, I have configured a desktop UWP C# application which users sign into and register using AWS Cognito Users and User Pools. The application also needs to communicate with another 3erd party API which uses a 1 time registration to return an OAuth2.0 access token and a refresh token. The access token expires ~20mins and then refresh token last the life of the request, typically forever until revoked by the user. I would like to store the refresh token so that it can be retrieved when the user signs in and is validated by Cognito. Is it okay to store this access token in the Cognito user attributes when they register or do I need to store it somewhere else? If I do need to store it elsewhere are there any AWS services which are typically used for this?
There is indeed an AWS service for this specific purpose. Its called AWS Secrets Manager.
Benefits;
Default encryption in storage and transit
You can use IAM to manage access control. So you could lock access down to one or two senior developers
You can use IAM for fine grain access control. This means you can lock the Secret down to a specific user and its secured at the storage level
Very simple to integrate with using the SDKs
Related
I'm trying to authenticate with Azure AD from windows service, so i tried to get access token using MSAL.NET library with acquiretokenbyIntegratedWindowsauth and it's working good on prem.
The intention is to migrate this windows service to azure web jobs, I challenging to get token that contains onPremisesSamAccountName claim silently from Azure AD without providing username and password.
Any help or workaround to get the token in this way.
Azure WebJobs won't allow usage of integrated Windows authentication.
There are two ways to get a token with user info from a background service:
Refresh token authentication (requires bootstrapping)
ROPC flow (username-password)
The first option's advantage is that no username or password needs to be stored.
But it requires that you have a bootstrapping process where the user signs in, a refresh token is acquired and stored somewhere where the background worker can get it.
The WebJob could then use that to get a token whenever it needs one.
The disadvantage of the first option is that it's more complex and the refresh token can expire, requiring bootstrapping it again.
The second option you might be aware of already as you mentioned not wanting to use username and password.
The advantage is that this approach is simpler, but it comes with that downside of storing a password.
Also the user account cannot have MFA turned on.
I am working on a .net MVC and web API project and using active directory to authenticate users to API, on authentication, a code is being returned from AD and I have to exchange the code to obtain a token and use that token to call the API, the question is why is the code returned and why do I have to exchange it for the token? can I directly obtain a token?
This is all because of security reasons.
OAuth 2.0 wanted to meet these two criteria:
All developers will not have an SSL enabled server and you should allow them to use non-HTTPS redirect URI
You don't want hackers to be able to steal access/refresh tokens by intercepting requests.
Since the Authorization Code grant has the extra step of exchanging the authorization code for the access token, it provides an additional layer of security not present in the Implicit grant type.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English) https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
Your question isn't really specific to Azure AD, and is more about the OAuth flow and why it is used.
The flow seems a bit complex, and well, it is, but there are reasons for all the things it does.
I encourage you to use authorization code flow instead of other approaches.
It has many advantages:
Your app will never see the user's password
The user cannot see your app's client secret
The user cannot see your app's access tokens (and neither can a man-in-the-middle attacker)
You get a refresh token that you can use to get new tokens whenever needed (you do need to specify the offline_access scope for this though)
The user can go through multi-factor authentication, federated authentication with ADFS etc., and your app doesn't need to care about that
Alternative flows and their downsides:
Implicit flow
Gives you a token directly without the code exchange
There is no refresh token
Mainly used in Single Page Apps, where refresh is done using a hidden iframe, but that depends on the user's session remaining active
If you use this outside a SPA, you can't really refresh the token, requiring the user to login again every hour
User can see and take your app's access tokens
Client credentials flow
Instead of accessing the API as a user, you access it as the app itself
Some APIs do not support this approach and require you to make calls on behalf of a user
This doesn't allow you to authenticate a user
Application permissions are needed to use this flow, which usually give very broad access to the entire organization
The upside of this flow is that it is very simple
Resource Owner Password Credentials flow
Do not use this flow
HTTP request to token endpoint with app + user credentials
Exposes user password to your app (!)
Does not work if user has MFA, expired password etc.
I have a service which needs to run under user context, because some endpoints of Microsoft need an user context to execute. My problem now is 01.09.2019 MFA is mandatory. So, at least at the beginning, the service needs a person who logs in, but this is not possible because it is an non interactive Windows Service. So my question is, it is possible to login as a user by code or not? If it is, how? And will the refresh token be stored in the aad cache?
UserIdentifier user = new UserIdentifier(Cred.UserName,UserIdentifierType.OptionalDisplayableId);
return Task.Run(() => authContext.AcquireTokenAsync(
"https://api.partnercenter.microsoft.com",
Cred.ApplicationId,
new Uri("http://localhost"),
new PlatformParameters(PromptBehavior.Auto),
user)).Result;
You'll need to have some kind of app that authenticates the user and stores their refresh token in a secure place like an Azure Key Vault.
Your background service can then use the refresh token to get a new access token and new refresh token.
You can use the access token to call the API and store the new refresh token over the old one.
Then if the refresh token does not work, you'll need to repeat the authentication process.
Refresh tokens can go invalid for some reasons, so your app needs to be ready for that.
it is possible to login as a user by code or not?
yes it is possible
In Authentication time the app receives both sign in info (the id_token) and artifacts (ex: an authorization code) that the app can use for obtaining an access token. That token can be used to access other resources -
This sample shows how to use MSAL to redeem the authorization code into an access token, which is saved in a cache along with any other useful artifact (such as associated refresh_tokens) so that it can be used later on in the application.
Google API OAuth 2.0 servcie Account C# ( drive api)
I am only targeting ONE Service Account.
I am looking in authenticating to a service account.
following this example:
Google example
As far I can understand, the token is permanent not 1h like other authentication type. Yet there is no mention of the token in the code.
Do I have to store this token? or do I have to request it every time I want to create the service, using the certificate?
Is the "service" creation code the same as described every time I need it. Or is this just for the very first time I request access to this account?
As I've commented, the article "Using Google Drive API with C#" part 1 and part 2, shows how to store the refresh token and use it to authenticate in the name of app.
It's also warning about the limitations of the service account, in many cases "useless" as you said.
Here's another one implementation of IDataStore.
Hope that help you! =)
Google offers a few options for authenticating users. One of them is Service Accounts which provides more secure communication between your app and Google server while authenticating users.
Normally, if you use Google oAuth library in server side, a shared key is used to authenticate user and to get a token which includes access_token, toke type, refresh_token, expire time. In this case, user should give you permissions.
However, when you use Service account, user is not involved and service account is used for authentication. In this case, in first time, you should use Service Account to get a token and store it in your DB. That way, you will be able to use it next time while sending API calls. And of course, for security reasons, this access token will expire. In this case, you will use refresh_token which returns when you get token for the first time. With using refresh token, you will be able get a new access token.
I have an ASP.NET Application created using the Visual Studio 2013 project template. For security, I chose Azure Active Directory. I have all of the login working, but I'd like to start using the Graph API to manage users in my application. I have created an Application Key to use with Azure AD, but I'm not quite sure how to go about making graph calls.
I've studied the code at https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet, but using the graph API in that way requires a token.
Is there a way to get a token from my ASP.NET application after it has successfully logged into AD that I can use to call the graph API? Maybe by adding a method to Global.asax?
Is there another way to call the graph API from an ASP.NET application created with this project template?
Indeed, you do need an OAuth token using which your web application can access the Graph API, on behalf of the logged in user. If you're using .Net, you are looking at the correct sample - OpenID Connect is the recommended protocol to sign-in the user and get an authorization code to access Graph API: https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet.
The OpenIDConnect (SSO + Auth Code Grant flow) begins when the user clicks Sign-in link. See the _LoginPartial view (https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet/blob/master/WebAppGraphAPI/Views/Shared/_LoginPartial.cshtml) and the SignIn Action in the AccountController.
The main magic happens in Startup.Auth.cs (https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet/blob/master/WebAppGraphAPI/App_Start/Startup.Auth.cs): It configures a delegate on the event AccessCodeReceived to redeem the OAuth Access Code for a Refresh Token and Access Token for the resource (Graph API) and puts the tokens in the token cache.
See AuthUtils class (https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet/blob/master/WebAppGraphAPI/Utils/AuthUtils.cs): The GetAuthToken method first tries to retrieve an access token from the token cache. If the access token and refresh tokens have expired, it re-authenticates the user to populate the token cache with fresh refresh token.
See TokenCacheUtils class (https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet/blob/master/WebAppGraphAPI/Utils/TokenCacheUtils.cs): It calls the AAD token endpoint to get an Access token for the resource (Graph API in your case), using the Refresh token using the code
Hope this helps