How to completely sign out a user using Oauth Prompt? - c#

I have been following the Oauth prompt sample Oauth Sample. Its working great when I login properly and get a token. However I am working on the use case when a user logs in using the wrong credentials. I am using await botAdapter.SignOutUserAsync(innerDc.Context, ConnectionName, null, cancellationToken); to sign the user out and it works since Oauth gets prompted again. However when the user clicks on sign in button again, it takes the wrong credentials again ( i.e same logged in credentials because of browser cache ) and doesn't allow the user to use a different account. I am looking to gracefully sign the user out so that he can choose another account to login. I understand if I add this to the right tenant (add my bot to right AD identity) it wont allow the wrong email/credentials to even get through but its something I have to work through for now. I don't know if this is intended but the sign out only destroys the token doesn't log you out of Microsoft online.
Thanks

Given that the SignOutUserAsync method only signs a user out of the token server, my guess is you will need to implement a custom method to handle a full sign out. This doc discusses sending a sign-out request and should serve as guidance on how to setup. If this isn't a perfect match, other options are listed in the menu tree.
Instead of relying on the SignOutUserAsync method, you would implement this feature in its place.

Related

MS Graph and Azure Active Directory

Problem: How to authenticate in MS Graph using Azure AAD access token.
Current flow:
My web app has AAD configured with "Log in with AAD"
If I log into AAD my demo app is showing and if I go to https://******.azurewebsites.net/.auth/me
then I get the access_token.
What I tried:
So I tried a couple of things and this was the last, I copied the access_token as code and tried to send it, didn't work.
I'm searching for a solution to silently use the already logged-in user and call MS Graph.
The reason for the error is that you have used the wrong code. Don't try to send the access token as a code, you should request an authorization code in your browser.
https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize?
client_id={client id}
&response_type=code
&redirect_uri={redirect_uri}
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345
In addition, redirect_uri is also a required parameter.
For the already logged in user you need follow the below steps for access:
Make sure you have enable the allow access token for the register app as below
Write code to acquire access token for the for the logged in user Reference
Now you can pass this token in other successive call to get the result.

How to get ADAL to check username before using cached login credentials to logon user to application

I have an ASP.NET MVC application that uses Azure Active Directory for authentication. All works perfectly except for this scenario.
Launch application and login using user#domain.com, the user is authenticated and application home page is displayed
Close browser (Logoff not implemented)
Launch application again and click login as another user
Enter username as abc#domain.com - This user is fake and does not exist
Expected behavior: Some error saying the user does not exist or login failed
Application behavior: Logs in user#domain.com by default without checking the new username that's entered.
Note: portal.azure.com works the same way.
Question: Is there a way to change this behavior so that the username is validated or authenticated before the cached token is used.
thanks
This is by design.We do not go to AAD for authentication every time, cached credentials as used as the tokens / cookies the client has received during the initial login are good enough to get access to the resources.
There are two ways to achieve what you are looking for
1) Implement Sign out( feasible and optimum solution)
2) Implement a Auth filter and apply at a global level so for every request it has to validate the token and user name provide by user.
Hope it helps.

access_type=online vs offline, how to know which one to use

I have implemented Google oauth2 server flow for web, the first time that user logins using his/her google account I have to use access_type=offline to get a refresh token and save it to database but after that access_type=online will be enough.
I have read that google issues limited number of refresh tokens per client (I think the limit is 25 from what I read while I was searching) so after I got the refresh token I just want to use access_type=online.
But before the user logs in how should I know if I have the account associated refresh token or not.
I don't want to rely on cookies as user may remove cookies, several people use the browser and cookie might not equal to the user I have its acount and ...
Any Ideas how to detect it with google oauth or something like that before showing the login button?
You can just continue to use access_type=offline. It just won't give you a new refresh token after the first time. This will work until the user revokes access for your client in which case you'll have to get a new one anyway.

How can I register a new user with a user-defined unique identifier when leveraging OAuth code flow?

I'm building a sign-up / login flow for a web site. I plan to use Facebook as my identity provider instead of rolling my own.
I have a good feel for the server-side login flow with Facebook:
Call FB login API to get a code
Exchange the code for a user access token
Inspect the user access token
Validate the user access token details
After these steps, I'd like to check if the authenticated user is already registered in my system. If yes, simply return a newly generated bearer token, so the user can make subsequent requests to resource servers to access protected data.
If the user is not registered in the system, however, then I'd like to register them by creating a database entry. Before creating this entry though, I'd like to collect one piece of information from the user. Namely, I'd like for them to tell me their desired 'username'. I will use this unique username as my database primary key.
I'm not 100% sure on how to securely ask the user for their desired username before creating the database entry. This is my question. :)
One thought I had was to create a "redemption code". This code would be encrypted and contain the user initialization details, a secret only the server would know, and a timestamp. Something like this:
code: {
mySecret: "super-secret-value",
expirationDate: "date-value",
user: { ... },
}
After seeing the user is not in my system, I'd respond with the code + redirect the client to a page where they'd be able to specify their username. Upon submitting their username + code back up to the server, I could decrypt the code, and validate mySecret to determine the code is not tampered. If all is good, create the user in the database with the user information from the redeemed code. Lastly, I'd generate a new bearer token for the user and send it to the client.
Questions
Is my proposed redemption code strategy a secure way of requesting a username before creating the backend DB entry?
If not, what would be?
If yes, what is a secure encryption/decryption routine to use for this purpose in C#?
Flow Sequence
Steps 1-4 from above correspond to "Login" through "Validate" arrows.
My proposed redemption code strategy corresponds to the purple arrows.
Red text corresponds to Facebook specific nomenclature.
Note, Stack Overflow does something very similar to what I want to do. Before creating your account on SO, it will ask you for your desired Display Name (this happens after authenticating via Facebook, Google, etc.). After submitting your display name, your account is registered.
Use open source IdentityServer3.
Whatever flow you choose its already standardized in their server. Including (if you want or need) OpenID, OAuth2 etc.

DropNet DropBox login, how to do it programmatically in a console application?

Question:
I'm using a DropBox csharp API from here:
https://github.com/dkarzon/DropNet
From the Unit tests, and the only working sample from here
https://github.com/dkarzon/DropNet/blob/master/DropNet.Samples/DropNet.Samples.Web/Default.aspx.cs
I figured that it works like this:
DropNet.DropNetClient client = new DropNet.DropNetClient(strApiKey, strAppSecret);
DropNet.Models.UserLogin login = client.GetToken();
client.UserLogin = login;
var accountInfo = client.AccountInfo();
str = accountInfo.quota_info.quota.ToString();
The probem is, it throws an exception on accountinfo. (System.Net.HttpStatusCode.Unauthorized)
Everything before works fine, I get the login (usertoken & usersecret) .
I think my problem is this part of the sample application:
var url = _client.BuildAuthorizeUrl(Request.Url.ToString() + "?dropboxcallback=1");
Response.Redirect(url);
Where it redirects to dropbox for a login...
I don't have a web application, so I have no URL...
What I have is a console application, that should make a backup of my database every evening automatically as a service, for which it certainly is very bad requiring a webbrowser and a user which has to type in email/username + password.
How can I do a login by directly supplying the hardcoded username and password ?
If I use the sample application, then it works, but that requires typing in the username and password on the web, and that sucks big time for a console application...
As far as I know from other API's (facebook, google, stack exchange etc.) you'll have to redirect your user to a webpage of Dropbox, where it will grant permissions to you to use it's account to perform things.
So in general it is not possible to achive this without a webbrower. Otherwise you'll have to perform really dirty hacks to hack arround the permission system of dropbox.
Please have a look at "OAuth 2.0 authorization flow" on google.
Here's a diagram I found at Yahoo which show's how it works:
For uisng the DropnetClient's 4 argument constructor also we need to build web based url and allow the user to authenticate his account this is compusory thing, accesstoken will generate after the user hit allow button in authentication process
As GameScripting explained the Dropbox API uses oauth which requires user login through the dropbox website to authenticate the access tokens.
Checkout the documentation here: http://dkdevelopment.net/what-im-doing/dropnet/ for the 3 step process.
What sort of application are you building? Normal process is to load a browser control inside the application and navigate to the login URL with it.
Also have a look at the sample Windows Phone app to give you an idea of how this process works: https://github.com/dkarzon/DropNet/blob/master/DropNet.Samples/DropNet.Samples.WP7/MainPage.xaml.cs
Instead of hardcoding the username and password, you can hardcode the OAuth access token.
First, create a simple program (using the same app key) that follows the standard browser-based authorization flow. Then use it to authorize the app with the desired user. This will give you an OAuth access token (a "token" and "token secret") associated with that user and your app key.
Then, in your service-style application, just hardcode the OAuth access token (using DropNetClient's 4-argument constructor).
It is possible, using SharpBox - tested, works.
One needs to acquire the AccessToken as a one-time-action manually, then after that, one can omit the login page and use the saved AccessToken.
http://www.jayway.com/2012/02/06/unboxing-dropbox-and-sharpbox-2/
The magic line is:
Globals.DropBox.Token = AppLimit.CloudComputing.SharpBox.StorageProvider.DropBox.DropBoxStorageProviderTools
.ExchangeDropBoxRequestTokenIntoAccessToken(
Globals.DropBox.config
, Globals.DropBox.AppKey, Globals.DropBox.AppSec
, Globals.DropBox.requestToken
);

Categories

Resources