This project has moved. For the latest updates, please go here.

ADFS 2012 R2 oAuth 2.0 SSO sample .NET

Jan 8, 2014 at 8:01 AM
0 down vote favorite


Can any one point me in the right direction. I want oAuth2.0 .NET sample that works with ADFS 2012 R2. The sample should manage the session cookies so my client application don't need to enter the password again and again for true SSO experiecne.
Coordinator
Jan 8, 2014 at 5:28 PM
Jan 10, 2014 at 1:04 PM
I had that sample but this also has same issue of ccokies and credential prompt again and again on same machien for same user :(
Jan 11, 2014 at 6:50 PM
Edited Jan 13, 2014 at 6:14 PM
First, opening 3 different threads for the same topic won't help you getting more answers. I've personally stopped answering as I'm still waiting for you to clearly explain what you want to do exactly. Aide-toi et le ciel t'aidera...

Secondly, I think you're misunderstanding what SSO is: it only aims at avoiding repeating the authentication process (and not the authorization one, as it should not be skipped in an implicit OAuth2 flow, even if the user has previously authorized your app: the impersonation risk is far too high. That said, I don't know if the last version of ADFS includes a kind of "confirmation page", as the authorization is classically not given by the end-user, but by his sys admin...) across applications and this only works when the authorization dialog is executed in the same context. In the case of ADAL.NET, I imagine that it's IE which is responsible of storing the authentication cookie in a per-user container according to the authorization cookie policy as the dialog seems to be more or less a web view. I'll try to get more info about the AD cookie validity scope.

In your second thread, you were talking about "multiple instances of the same application on the same machine for the same user": in such a case, you have to store yourself the access token returned by the ADAL.NET library so the entire workflow won't be needed after the user has given his credentials. You have plenty of options: storing it in the isolated storage, in the user's AppData folder, in the cloud... or everywhere you might think of.
Jan 13, 2014 at 7:37 AM
First of all thanks for the reply.

What I understand now from SSO
Authentication = Credential Prompt
Authorization = Token or Key to access

From the same context you mean application that i am using ADAL.NET, I get token for UserA and Resource1 (Relying party), now when ever from the same APP I want to get token, I can change the Resource2 and ADAL won't ask for authentication. This is true and working as desinged.

Here is my architecture details for SSO that are different from social SSO, because we have desktop clients that are taking calls from the Switch, call center type.
  1. Different servers applications like ACD (automatic call distribution service having socket end point) etc , all the servers application are located on one same machine and ADFS 2102 R2 is on different machine and client is also on different machine.
  2. COM DLL that will wrapp the ADAL.NET and deploy on each client machine, my client app will use this DLL to be authenticated and authorized with ADFS 2012 R2.
  3. One Relying party will be configured to point My Web API. But this Web API will not have any business logic because this is the requirement of ADFS 2102 R2 to configure a RP and I did not have any implementation in the API to give the access to MY API bases on the token.
  4. On client ID is registered with ADFS using Power shell command and passed it My Web API URI for both resource and redirect URI.
  5. My client app will be authenticated and get the token after that they are logged in, now from the same client machine there is another app that is used to do configuration online in the database, when I launch this app i use the COM DLL and call the same acquire Token with same URI and Client ID it prompts for credential, is this correct behavior for SSO because same client ID is already authenticated from the same machine this time it should return the token only not the credential prompt? I have configured form authentication on ADFS? I heard that ADFS do writes cookies on client machine?
Jan 13, 2014 at 6:11 PM
Edited Jan 13, 2014 at 9:38 PM
Nice explanation, even though you now describe totally new symptoms (purely related to SSO this time, while your previous topic -https://katanaproject.codeplex.com/discussions/483923 - was rather related to "access token storage and multiple instances" :P)

To be honest, I'm not an AD expert and I asked a coworker to take a look at your question, without success I'm afraid. I saw that you didn't get lots of useful answers on MSDN/Technet boards and that Dominick Baier - probably one the best specialists - was not able to help you either... which leads me to believe that I won't be able to give you a "perfect solution". That said, if you're still unable to make ADFS and ADAL.NET work for your SSO scenario (which would be surprising as ADFS was built with SSO in mind ; I'm sure that someone at Microsoft has the good answer... but who?), you might consider:
  • Using a standard OAuth2 desktop client library (there are plenty on Nuget): this will allow you to determine whether your issue is caused by ADAL.NET (ie. because its web view flushes the authentication cookie on app' disposal) or by ADFS itself (ie. because it doesn't emit usable cookies). If it still doesn't work, you could also consider creating a custom web view using another engine (why not GeckoFX? https://bitbucket.org/geckofx/geckofx/wiki/Home) and intercepting yourself the OAuth2 redirects (through the Navigating event in GeckoFX).
  • Or... creating your own OAuth2 authorization server using the OAuthAuthorizationServerMiddleware and the CookieAuthenticationMiddleware (yeaaahh, it's an OWIN board after all... :o) and delegate the entire authentication/authorization process to ADFS using the OAuthAuthenticationClientMiddleware I've presented in your first topic (I've removed the fork as my proposal has been rejected [hum...], but I'm planning to submit it on a custom repository ASAP. In the meantime, consider registering to Auth0 and subscribe to their free plan). This way, you'll have a full control over the cookies issued by your custom authorization server, without worrying for ADFS emitting buggy cookies. Thus, your client apps won't trust ADFS anymore, but your custom authorization server, configured to delegate the authentication/authorization part to ADFS. I'll try to upload a little schema explaining the whole process ;)
Good luck.
Jan 23, 2014 at 11:15 PM
So, in your Step 5, you have an AppDomain that hosts ADAL and makes an auth request and gets an AccessToken for your RP.
Then a second AppDomain is created in your ComCallableWrapper that hosts ADAL. You aren't marshalling the AuthenticationResult from the first domain to the second, and ADAL doesn't use cookies as its token storage mechanism (pop open the code, it's JWT strings in a dictionary in the local AppDomain).

You can replace the token cache with one which will persist the data in a fashion which would be available cross-AppDomain. See Vittorio's article about the TokenCache at http://www.cloudidentity.com/blog/2013/10/01/getting-acquainted-with-adals-token-cache/ and and the Native Client to Web API ADAL sample code in this class: http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf/sourcecode?fileId=96196&pathId=1866494180
Jan 24, 2014 at 12:51 AM
Edited Jan 24, 2014 at 1:24 AM
As tokens are emitted for specifics clients/relying parties, I don't see how a cached access token retrieved by an application A could be used by an application B to access user's protected resources, or even allow application B to retrieve a new token without having to execute the whole authentication/authorization flow. He could, of course, reuse the same client id and share access tokens with every installed app, but I imagine it would not be a reasonable perspective here (notably, you couldn't decide that users of app B are not allowed to access app A and vice-versa).

The problem here is not to store the AuthenticationResult/access token - and I'm sure there are far easier ways to store that - but to find a way to skip the authentication flow (and not the authorization one) so the users don't have to enter their credentials in app B when they previously logged in app A.

And while AD has the nice concept of "multi-resource refresh tokens" (see the link you mentioned and http://www.cloudidentity.com/blog/2013/10/14/adal-windows-azure-ad-and-multi-resource-refresh-tokens/) that allow an OAuth2 client to access multiple user's resources - typically, it allows accessing "Web API B" with a token that has been originally given for "Web API A" -, it can't solve, unfortunately, the concern discussed here, as you have to use the same client id in every successive call.
Jan 29, 2014 at 12:01 PM
Edited Jan 29, 2014 at 12:09 PM
Hi TetsujinOni, PinpointTownes

I try to clearify all the bits.

For point 5. I have configured an RP but this is the requirement of AD FS 2012 R2. When I get the token my actual RP is a TCP end point windows servcice to whom my client app will pass the token and that service will validate the token and then give access the permission to the user. The RP i have configured for AD FS will Just used for oAuth2.0 flow termination and this RP will not have any logic. The SSO solution will be internal to the compnay and will run on intranet desktop and web clients. No need to compare this with social web sites where oAUth access token is passed to the REST based Web Service and access API's. I don't have any web service that can require token so I will use one of my main TCP End point Server that is managing all the clients permissions from the database and grant access on different reosurces or feature with in the applications.

The COM DLL will wrapp the ADAL.NET and this will be regsiteration free COM. I heard AD FS writes session and persisten cookies on client machine. Session cookies can be used to avoid credential propmt wihin the Same session or context of the application that has loaded the COM DLL. The persisten cookies can be used across the applications but not sure if ADAL.NET is using any of the cookies or not. When other applicaiton runs it will also load the COM DLL it means every applciation on the same machine will load the COM DLL in it's application process. I think thi makes senses.

The applicaiton that can run from the same machine have same clientID so that credential prompt can be avoided i thought it auomatically handled by ADAL.NTE if it is using persistent/sesison cookies. For example if I configured windows authentication on AD FS 2012 R2 and alos enbale IWA in internet explored then for domain user first time I opne applicaiton and it ask for credential using windows native dialog I enter and also click on save password after that I open my seocnd app it won't ask for password(I think it uses kerebros/NTLM). It means it is working fine but for form based authentication it does not work. In windows authentication for second app I get different token.