How do i pass authorized user from one application to another running in same server? - asp.net

Architecture of my application is something like this.I have a application which is hub for many other applications which allows user to pass credentials. After credentials are checked, Hub application presents one or more applications which the user is allowed to use. If user has only one application it redirects directly to the application. How do i maintain the authorized state of the user passed in hub application and access them again in the children application?

There is no "one way" to do this. But one way to do this is to provide a Javascript Web Token (JWT) back to the client if they log in successfully. The server can then know, authentically, who the user is that made the request if the client provides the JWT as a request header (typically "Authorization: Bearer JWT- goes-here). You can keep the JWT in some kind of local storage like IndexDB to share between applications (assuming same domain URL) and delete it if the user logs out.
Also, in case it's not obvious, definitely use HTTPS. There is no excuse not to in 2019, with the existence of LetsEncrypt.
if you are using Express.js use express-jwt and jsonwebtoken packages to accomplish this scheme.

Related

IdentityServer4 Web Login via id_token or access_token

Context
I'm building a hybrid native/web app. Part of it will be API driven, and part of it will be webviews showing an existing website.
Once logged in with my OIDC SDK (Amplify/AppAuth), I can access the user's id_token and access_token.
However, because the webviews used in the SDK are not controllable, I cannot reuse the cookies generated by my identity server.
Question
For the reason above, I'm trying to login a user from their id_token or their access_token. (both are JWTs)
I believe this isn't supported by IdentityServer4, but I am looking to implement something myself.
What I have found so far:
1) id_token_hint
OpenID Connect Core 1.0, Section 3.1.2.1, id_token_hint parameter:
OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the End-User's current or past authenticated session with the Client. If the End-User identified by the ID Token is logged in or is logged in by the request, then the Authorization Server returns a positive response; otherwise, it SHOULD return an error, such as login_required. When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not; however, the server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need not be listed as an audience of the ID Token when it is used as an id_token_hint value.
If the ID Token received by the RP from the OP is encrypted, to use it as an id_token_hint, the Client MUST decrypt the signed ID Token contained within the encrypted ID Token. The Client MAY re-encrypt the signed ID token to the Authentication Server using a key that enables the server to decrypt the ID Token, and use the re-encrypted ID token as the id_token_hint value.
According to this optional spec of OpenID, I should be able to use the id_token on the /authorize endpoint to login the user. I know this isn't implemented in IdentityServer4, but I'm looking at AddCustomAuthorizeRequestValidator to do that. However I'm not sure how to "get a user from their id_token" in the code. Do you have any pointers?
2) using AddJwtBearerClientAuthentication
This method sounds like I could authenticate from my access_token, but I can't find much documentation on how to use it.
THE PROBLEM
Let me know if I am misunderstanding requirements, but it feels like you have 2 different apps and are trying to make them feel like a single integrated set of screens.
The default behaviour will be as follows since web views are private browser sessions and cannot use system browser cookies. You want to prevent the second step since it is a poor user experience:
User signs in to the mobile app
Whenever a secured web view is invoked, there is a new private browser session with no auth cookie, therefore requiring a new login
COMMON APPROACH: SUPPLY A TOKEN TO THE WEB VIEW
It can be common to forward the mobile token to the web view, if the two apps are part of the same user experience. If required, extend the mobile app's scopes to include those for the web app.
You should not need to issue any new tokens or change the security model of either app. But the mobile and web apps need to work together on a solution.
POSSIBLE WEB VIEW SOLUTION FOR A SERVER SIDE WEB APP
This might be the simplest option:
Provide new .Net Core web back end entry point URLs that require tokens instead of cookies
The mobile app could then call those endpoints from web views, and supply its own token in the Authorization Header of the web view request
The web back end could then forward mobile web view requests to your Web APIs
The code to add the Authorization Header to a web view request may be a little tricky but there are ways to do it:
Android
iOS
POSSIBLE WEB VIEW SOLUTION FOR AN SPA
An option that works for Cookieless SPAs is for the web view to ask the mobile host app for an access token via a Javascript bridge. Some code of mine does this for a cookieless SPA:
Web UI Code to Call the Mobile Host
Android Code
iOS Code
You can clone / run the mobile github repos from your local PC to see the solution. I will be writing up some notes on this in my blog's Mobile Web Integration Post.

Securing communication between mobile app and RESTful service WITHOUT a username and password

I've been trying to work out if it is possible to authorize communication between a mobile app and my ASP.NET web api service without the user having to authenticate with a username and password. This is important because users of my app don't login at all and never will. All traffic will of course be sent over HTTPS.
This means I can't use OAUTH or BASIC authentication to authenticate the traffic as these require credentials.
So I need some method to securely store some kind of authentication token that is packaged in the app that is only accessed when it needs to communicate to the server and can't be "discovered" by a determined hacker.
This may of course not be possible.
Thanks.
In general it is not possible. Your server should never trust it's clients. Hackers can examine your client app and create equivalent one.
But you can make life of hackers significantly harder, if you:
Use custom cliest sertificat for HTTPS, look here.
Use temporary access keys in http request. Application should request for new temporary access key your server. Part of the key server will send in response and another part will be sent via Cloud Messaging. Combine parts of the key in some non-trivial way.
Obfuscate your app.

How should I share authentication from a desktop application to a web application using OAuth 2.0

I have a RESTful API written in ASP.Net that implements OAuth 2 for authentication, and it's currently accessed through a web application. I've also got a legacy desktop client that accesses the same resources directly (not through the RESTful API and without OAuth, but using the same login credentials and hitting the same database). The requirement I'm trying to meet right now is to allow a user to click a link in the desktop application in order to open the web app to a specific screen, and when they do, to have the web app authenticate automatically so that they don't have to manually log into it (since they've already logged into the desktop app).
I'm trying to work out how I can handle this within the constraints of the framework. I'm not too familiar with OAuth 2 in general, but from what I understand I shouldn't share tokens between clients and there are no flows specifically for this kind of hand-off (unless I'm missing something). Worst case scenario, I could generate a temporary token outside of OAuth that's used by the web client to authenticate rather than a username and password, but I'm hoping to avoid stepping outside of what's already in the framework to do what I need to do.
So the question is this: is there some decent way built into the OAuth 2.0 framework to handle this sort of "handshake" between two applications, or should I just build my own method of dealing with it?
Using temporary one-time tokens is actually part of OAuth spec (authorization_code grant type). In this case this short-lived code can be exchanged for access_token (and refresh_token). You will have to implemenent generating and validating of this authorization_code.
If you are using OWIN OAuth middleware:
You can generate the code at separate API endpoint accessed by your desktop client app.
After receiving token, pass it to your browser and direct it to auth endpoint with grant_type=authorization_code over secure connection. Example: call Process.Start("https://example.com/ExternalLogin/authorization_code_goes_here"). At the webpage redirect user to your OAuth Token endpoint with grant_type=authorization_code.
AuthenticationTokenProvider.Receive will be called, in which you will validate your token. (Example code here).
After successful validation OAuthAuthorizationServerProvider.GrantAuthorizationCode will be called, in which you will process the authenticated user in the same way you process it with grant_type=password.
Remember that your token validation logic should ensure that your tokens are short-lived, usable only once and transmitted over secure connection.
This is sometimes called "single sign-on" if you want to research this topic further.

How to Anonymously Authenticate between a VB.Net Desktop App and ASP.Net Web App

I'm looking for a way to pass some sort of credentials or Authorization token from a VB.Net Client to an ASP.Net web application that allows the Client to auto-login to our Forms-Authenticated website. If a user is logged into a local application, I want them to be able to view some web pages without having to login to the website as well. The credentials are not the same between the apps, but I would just like to pass some sort of encrypted token or key to the web page so I know they are coming from the desktop application. Is this possible without requiring a username and password login?
I also need to make sure this URL that is used cannot be simply copied and used from another location, so I'll need to include some sort of information in the encrypted value to know where it's coming from.
I know how to login the user with Forms Authentication and all that, just need to figure out the best way to secure this. Thanks!
OAuth is commonly used to allow desktop applications to access a user's private data on a web site. Since you're using .NET, I suggest you check out DotNetOpenAuth which includes sample OAuth web sites and client applications. It allows for this secure token to be passed that can tell your web site that the desktop app is the one making the requests and (usually) whose data is being accessed.
The best part about the OAuth solution is your desktop app never has to ask for the user's credentials. No credentials are in the URL. And if the desktop application is ever compromised (perhaps by the computer being stolen), the web site can kill the secure token the desktop app was using to cut off access without requiring the user to change their password.
You might want to look into issuing client-side certificates for these applications. Basically, you generate a certificate that you install with the client application and then on the server side, you check the ClientCertificate property of the HttpRequest instance exposed by the Request property on the current context.
Note that what you are doing is really a very bad idea, in that applications should never be assigned identity, only users. To that end, you should be authenticating each and every user that is using your app, not considering the application to be the identity. It's commonly considered a bad practice to do such a thing.
You can share credentials between the applications using ASP.NET Client Application Services.
Here are some resources:
Client Application Services
Client Application Services with Visual Studio 2008
Is your desktop app running on machines that are in the same domain as your web server (i.e. all in the same company)? If so, Integrated Windows Authentication is your easiest solution.
I think its best idea to use a web browser control inside the desktop application .
Then use the WebBrowser1.Document most probably
WebBrowser1.Document.Cookie
get if the user is singed in.
I also need to make sure this URL that
is used cannot be simply copied and
used from another location, so I'll
need to include some sort of
information in the encrypted value to
know where it's coming from.
If you store the encrypted value in a cookie or as a field in a form (POST request), then the credential is no longer in the URL and so it can't be easily copied (note that I said "easily").

How do you debug an ASP.Net application accessing an OAuth secured API?

I know there has to be an obvious solution to this problem and I am missing it, so I would much appreciate someone enlightening me so I don't spin my wheels...
I am writing an ASP.Net application that will interact with a service API (Evernote specifically). Evernote requires OAuth for security and before I can actually interact with the objects I need to obtain a token.
The workflow goes like this (explaining it to myself as much as anyone else!):
Build a url with my development api key and secret key and some other OAuth stuff, send it to Evernote to request an access token.
Send the url as a request to Evernote and pull the new access token out of the response
Build another url with the access token to request an authentication token for the user. This url goes to a page the user must interact with to login (if they haven't already) and then authorize my application to access their account. The last param of the url I build is a callback url which will be called from Evernote's servers.
If all goes well, Evernote will request the callback url and include the new authentication token as a param.
Once my server receives the callback with the embedded token I can use it so that my app can interact with the users' notes on subsequent requests.
The problem is that I'm writing this app on a local box, not an ISP under a public domain. So my callback is to the localhost server. Of course, localhost is relative, so Evernote can't resolve my callback... I can't ever receive an authentication token and debug at the same time.
There has to be a way around this problem because this authentication model is not unique to Evernote (by a longshot... Flickr uses it as do a lot of other services). So can someone tell me how to set things up so I can get the authentication token and still be able to debug on my local box?
Help is much appreciated!
OAuth is quite tough to implement. It may not be the answer you're looking for, but this is how I managed to get the job done:
Write some code on my local dev machine.
Run a bat file (or alternatively hook a post-build event in VS) that executes a msbuild deploy script and deploys the application to a test server.
Run the application on the test server. After obtaining the request token and requesting for authorization it redirects to the Evernote website.
After successful authorization the Evernote website redirects back to my test server and the authorized request token is exchanged for an access token.
Instead of debugging (I don't have VS on the test server) I examine the logs of the application (the logging I used was as simple as writing to a text file).
Rinse and repeat
For the purposes of testing I registered a temporary public subdomain (e.g. testing.oauth.mydomain.com) so that Evernote will be able redirect to that url.
According to this (How do I develop against OAuth locally?) the callback is issued by the browser, so it should be able to hit localhost.

Resources