Several question on Oauth2 on ADFS Server 2016 - oauth-2.0

I'm used to working with ADFS for a long time already and recenlty I was asked to do a proof of concept with Oauth2 on ADFS. Struggling through terminology I managed to set most things up, but still I do have some unanswered questions. Hope someone can shed some light on these...
For SAML / WS-Fed relying parties, it is possible to set custom web content, using Set-AdfsRelyingPartyWebContent. Is this also possible for web api relying parties created in an application group?
Would it be possible to add claims to a client authenticated with client_id / client_secret (server application in ADFS terms) when using the client credentials grant flow?
Even after setting the 'IssueOAuthRefreshTokensTo' 'AllDevices' on the web api application, I still don't receive refresh tokens. What am I missing here?
When posting a token issued by our ADFS on e.g. jwt.io I receive an 'signature validation' error. How can we resolve that?
We would like to set an audience for the access tokens, so applications can use the audience instead of using the appid to verify if they can consume the token. Can we modify the audience?
What does add-adfsclient do? Does it create a client_id, which can then be linked to a relying party (with Grant-AdfsApplicationPermission), thus enabling OAuth2 for an existing relying party?
When configuring a ad user principal for a server application and use 'password' as grant_type with the client credentials grant flow, I cannot seem to find the correct syntax, as ADFS always give the error 'MSIS9622: Client authentication failed. Please verify the credential provided for client authentication is valid.'. I have used the syntax 'user#fqdn' for the username.
Thanks you for helping me out here!

Let me try and work through these.
In ADFS, OIDC applications and WS-Fed / SAML RP are completely different. You can't mix and match.
jwt.io has a signature error because it doesn't know the .well-known endpoint to get the key. Refer this.
To get extra claims you need to add an API as that is the only place for claims rules.
To get a refresh token, you need a scope of "offline_access".
For resource owner password, user name and password are separate fields. Refer here.
Feel free to ask more questions. Just expand your question.
Also, samples here. Look at the menu on the LHS.
Update
What do you mean by "can modify web content on a per relying party basis"?
Re. jwt.io, read this.
For refresh tokens, read this. It seems ADFS doesn't follow the spec here.

Related

How do I validate a token coming from a third party using the same ADFS authentication server?

An application A (me) needs to communicate with Application B and the communication needs to be secured using ADFS (OAuth2 Client credentials grant flow). Both A and B get their tokens using the same ADFS authentication server.
Reading the Microsoft documentation, it's pretty clear to me how my application A need to get a token from the authentication server and send it to the application B.
However, what I don't understand is how I can validate a token received by Application B.
I also struggle finding examples showing endpoints and JSONs. Is there any resource I can double check?
Thanks!
To validate the JWT, look here.
Basically check issuer, aud, expiry, signature etc.
jwt.io has a bunch of libraries to do this.

how would authentication be done in OAuth2 without OIDC?

I know there is lots of material on this point out there but I still dont quite get it.
I know that OAuth2 is not for authentication and that you need OIDC on top to have authentication.
But still don't quite understand why.
If I look a the implicit flow, one of the steps is that the user authenticates to the authorization server and an access token is then issued.
This is authentication, isn't it?
So why do we still need OIDC and the ID token? Is it because the access token itself is not enough and the JWT makes sure the user can be authenticated later on by the backend services?
And how would you do authentication if you only had OAuth2 and no OIDC?
Disclosure: I work for Ping Identity.
I wrote a blog on why OpenID Connect is useful on top of OAuth 2.0, and I think it would help out here.
https://developer.pingidentity.com/en/blog/posts/2019/oidc-adds-authentication.html
Basically, the OAuth 2.0 framework provides a way for the client to ask the authorization server to go and get authorization from the resource owner.
ie, the client says to the authorization server, "I need to access a protected resource owned by John, can you go ask John to authorize this access." The authorization server can then do it's thing and come back with an access token to the client to access the protected resource.
However, if the client asks, "How do I know it was actually John that provided authorization?" the OAuth 2.0 framework doesn't give a way to answer this.
OpenID Connect provides that extra ID token, in addition to the access token, that the client can check to see if it's John.

Which grant type : Implicit or Auth code (with No secret key) is suitable for Single Page Application(SPA)?

I went thru multiple posts saying how implicit grant is a security risk and why auth code grant with AJAX request to Authorization server should be used after redirecting to application (without client_secret passed to Auth server).
Now in 2019 there is no CORS issue as I can allow app domains on authrization server.
I have following concerns
If I use implicit grant:
Now implicit grant has security issues as Authorization server redirects to application server with token in url.
If I set expiration time to 5 to 10 minutes, after expiration, user will be redirected to login and its problematic especially if he is filling up important form on application. What to do in this scenario? Note that there is no refresh token in Implicit grant to update with new token, so refresh token is out of the picture.
If I use Auth code grant:
Suppose if I hit AJAX request after getting redirected to my main application site, and get token in exchange of code,
Auth code grant uses client_secret. And in javascript app where anyone can see the code, we cant use secret.
Assume now if I dont use client_secret. There are multiple sites that use auth server say site 1, 2, 3. Now if we say dont use secret, anyone can make host entry in nginx server that will have my site's domain name but his own IP address. In this case host injection is the issue. How to deal with it?
What approach should be taken here? I am more inclined towards auth_code for SPA but the issue is how to deal with client_secret?
Thank you for reading.
There are multiple links that recommends use Auth code grant instead of SPA. A few out of multiple links :
https://www.oauth.com/oauth2-servers/single-page-apps/
https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926
You've already linked references that make it clear that you should NOT use implicit grant in an SPA. Your confusion seems to come from your assumption that the code grant flow requires use of a client secret, but that is not the case. A SPA, like any browser or device app, is (should be) a PUBLIC client, and cannot be trusted with a secret. Therefore, it does not use a secret. The client secret is suitable ONLY for use with private clients, which is to say, server-side code calling the auth api.
the 2019 recommendations are to use a PKCE variation of the Authorization Code Flow that does not need a client secret:
https://brockallen.com/2019/01/03/the-state-of-the-implicit-flow-in-oauth2/
There's some write ups and code samples on my blog that might be useful to you - I updated this one on messages recently:
https://authguidance.com/2017/09/26/basicspa-oauthworkflow/

OAuth 2.0 for REST Web services

i'm implementing a REST layer for an existing application. I have my userid and passwords stored in database and i would like to authenticate these credentials while calling my REST services. Note that this is a standalone application.
After investigation, I figured out 2 ways.
Basic implementation with HTTPS - this approach makes sure that
userid and password passed is not tampered by Man in middle attack.
Using Authentication Token(JWT) - user initially passes his userid
and password and server gives back an Authentication token.Once user
have an authentication token that could be used for subsequent
request.
Using OAuth 2.0 - I'm very confused in this approach. After reading the docs and specification, I found that since my application
is standalone, I need to implement Authorization Server, Resource
Server etc.
I'm asked to implement OAuth here, but i'm not convinced that OAuth is required in this scenario. I'm more inclined towards just implementing JWT(tokens)
Is OAuth really mandated in this scenario. What i understand about OAuth is it is used when you already have a service like Facebook/ Google.
Could someone pls confirm if my train of thoughts are correct and if OAuth 2.0 is required in this case?
The primary goal of OAuth 2.0 is to allow users to authenticate to use a client application via a third-party authentication provider (e.g. Google, Facebook, etc.), without exposing their credentials (typically a username/password) to the client.
In your case, if users are only ever going to authenticate to your system using their credentials in your database, then implementing OAuth 2.0 doesn't add any substantial value for you.
The OAuth 2.0 specification does define a "Resource Owner Password Credentials grant", intended for legacy use cases, that would apply to your situation: a user sends credentials, and you return an access token (that could be a JWT, if you like). If it's desirable from a management or marketing perspective, you could implement the Resource Owner Password Credentials grant and legitimately state that your application "conforms to a subset of OAuth2, as defined by RFC6749".

Does Google OAuth2.0 support an OAuth-flow for a Resource Owner Password Credential Flow?

Hello kind people of the internet.
Does Google OAuth2.0 support an OAuth-flow for a Resource Owner Password Credential Flow?
...and if so, then:
A.) can this type of OAuth flow be tested on the Google OAuth2 Playground?
B.) are there any examples of the "Resource Owner Password Credential Flow" with Google OAuth2.0 and the Google APIs?
Per an OAuth presentation recently in Oslo NDC 2013, this subject flow apparently skips the authorization end point all together and directly talks to the token end point of the OAuth2 server. The request syntax incantation would supposedly look something like this:
grant_type=password&
scope=resource&
user_name=owner&
password=password&
My understanding is the Resource Owner Password Credential Flow is for trusted applications in a back-end enterprise type of situations (where a name-password pair could be securely stored).
This particular OAuth flow would require no end-user consent interaction (no pop-up of a browser to Accept, then get a returned authorization-code, etc). In this subject flow the access & refresh token are directly returned, again: with no end-user interaction (albeit after an entry of a username-password).
Looking through the Google OAuth documentation ( link to Google OAuth2 docs ) there does not seem to be any mention of anything resembling Resource Password Credential Flow, but not sure that necessarily means it is explicitly not supported by Google.
Any help or advice would be much appreciated.
thanks in advance
Dear kind internet person,
it is true that Resource Owner Password Credential Flow is not supported on Google but google suggests you use the Installed Application Flow, which is described in: https://developers.google.com/accounts/docs/OAuth2InstalledApp.
You would need to create an Installed Application in the Google Console (https://code.google.com/apis/console), when you do that you can fetch the client_id and build a GET request with the parameters, which would look like so:
https://accounts.google.com/o/oauth2/auth\?
scope\=<scope>\&
redirect_uri\=urn:ietf:wg:oauth:2.0:oob\&
response_type\=code\&
client_id\=<client_id fetched from google console>
You would construct this URL and navigate to it on your browser, allow access for the app and google would give you what I believe is a code which you can use to get credentials. You can use those credentials to get an access token and refresh it, and this credentials is permanent. There's a good example of that on github. Note that you only need to get those credentials manually once, and then you save those credentials somewhere and keep using them to get/refresh tokens.
Hope this helps!
As far as I know, No. The OAuth 2.0 stuff is for Google accounts, for which Google does authentication.

Resources