I am trying to integrate constant contact service in my .net desktop application. What to set redirect URL for desktop application?
In an OAuth 2.0 flow where you are using a Client Application (such as a .net desktop app, mobile app or anything else that is not a SaaS application), the value of the redirect URI doesn't tend to matter as long as it is in the valid URI format supported by the vendor. With the Client Flow of OAuth 2.0 (see here for more information), you would open up a web browser in your application, load the OAuth grant access flow and watch for a 302 redirect to your predetermined redirect URI. When you see that redirect, you would intercept it instead of loading that page in the web browser your application loaded and then pull the authorization code off of the URI fragment.
Simply follow the follow up flow for exchanging the authorization code for the access token, save the access token in the local application settings for future use and you're all set. This is standard for all OAuth 2.0 providers, not just Constant Contact. In .Net, I tend to use a WebView to load the flow in the application.
Related
I have this legacy intranet app using an AngularJS SPA consuming an an ASP.NET Web API (on .NET 4.6.1) and I can't manage to get the user authenticated on the domain inside the API, when calls are made by AngularJs.
Inside the API I have situations where I need to get the domain authenticated user. I have tried several combinations inside IIS to set both the AngularJS app and the API with Windows authentication, Impersonation, Authorization Rules. I've read several questions in Stackoverflow and other forums and also searched through several articles but I can't manage to find a solution, I'm feeling helpless in this one.
When I make a direct call to the API using a tool like Postman or through Swagger, System.Web.HttpContext.Current.Request.LogonUserIdentity.Name shows the correct authenticated user.
When I make the very same call to the API but through the client, like loading a page that requests data from the API, the user shown in LogonUserIdentity, is the one set on the app pool.
The authentication between the client and the API uses bearer token.
Here's my current scenario:
IIS:
Windows authentication enabled for both the client and the API, Impersonation enabled for both the client and the API
Authorization rules for ASP.NET and IIS set with allow all users for both Client and API
Session state in-proc, using cookies and with UseHostingIdentity set to false on both Client and API
Both the client and the API are using the same AppPool, with integrated Pipeline, .NET CLR v4.0,
If there's more info to supply please let me know, I'll update the question with the required info.
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.
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.
I'm building a mobile application (that might also later become a web application). The server side is a ASP.NET MVC + Web API application and I'm thinking about ways how I could implement the service's user management and authentication.
How should I implement the registration/login screen in the app? Offer native app forms, that will send just API requests to the service or is it preferable to show a web browser component and display the website's login page and then extract a token after the user logs in? I see the first option is more user friendly, but the second one will let me change the login / registration page (like for example adding external authentication providers) without breaking older versions of the app.
My second question is regarding the external authentication providers. ASP.NET Identity has good support for them and it is quite possible to let users register using Facebook or some other OAuth2 provider. Does it make sense to add support for external authentication providers when I plan to expose the app's API publicly? Are there any reasons why that is not a good idea?
Your first option is best if you believe your users will trust you to manage their passwords. You make a secure call to your service, have the service produce a bearer token as the result. That would be an anonymous call. I used the answer from this question to get me going down that path:
Get IPrincipal from OAuth Bearer Token in OWIN
If your users are less likely to trust you with their credentials, then the web view and external provider is a good alternative. You would need to work with providers that support the "Implicit Grant Flow" since don't want to share the apps clientid and client secret on the mobile device. This approach involves using a web view to login in, and then capturing the token on the client uri fragment on the response. I think it is on a location header, but don't have a working example in front of me. Something like:
https://your.domain.com/#access_token = 8473987927394723943294
you would pass that token with each api call afterwards .
Good luck!
I am trying to do something like this:
I have a MVC4 Web App and a Web-API service (hosted on two separate roles in azure)
Another role runs CustomSTS1.
The MVC Web App trusts the CustomSTS1
Now the customer logs into the site he is redirected to the STS login page.
Once logged in, he is redirected back to the MVC Web Site.
From this web site, the customer performs actions, which in turn invoke the web-API Service.
I have the SAML token in the web app, which I pass to the WebAPI service.
Now when I try to validate the SAML token at the Web API side, I get a
Message=ID1032: At least one 'audienceUri' must be specified in the SamlSecurityTokenRequirement when the AudienceUriMode is set to 'Always' or 'BearerKeyOnly'. Either add the valid URI values to the AudienceUris property of SamlSecurityTokenRequirement, or turn off checking by specifying an AudienceUriMode of 'Never' on the SamlSecurityTokenRequirement.
This is without the Web API service trusting the CustomSTS1
Once I setup the trust,
I am always given a HTTP 401: UNAUTHORIZED, whenever I try to make a HTTP Get request to the WEB API Service.
Now, My Question is, (I know that my current approach is definitely wrong)
How do I setup the Trust relationship with the CustomSTS1, such that the WebAPI service is able to do an ActAS on behalf of the user logged into the MVC site?
OR
Is this architecture wrong?
And is there another way to achieve this?
That approach is wrong conceptually. The MVC application should negotiate a new token for the Web API in the STS using ActAs. That's how it traditionally works for SOAP Services. However, Web APIs are moving away from SAML as it is a complex format that relies on different WS-* specs. OAuth 2.0 is becoming the standard in that area if you want to support SSO at that level.
Another approach is to establish an implicit trust between the MVC app and the Web API, so all the calls to the Web API from the MVC app are done through a more standard Http auth mechanism like Basic Auth using an specific set of credentials that only the MVC app knows. The info about the logged user in the MVC app is passed as additional information.
Regards,
Pablo.