Implementation-
Enable OAuth2.0 flow between LinkedIn & Forgerock AM where FR AM acts as a client and LinkedIn is the OAuth provider.
Problem-
We are integrating "LinkedIn Sign" into one of our apps using OAuth2.0 with Forgerock AM as a client. Right now, Forgerock, which is acting as a client, passes PKCE parameters in the authorization request endpoint to LinkedIn (code challenge & code challenge method) and we receive the authorization code along with the state parameter. But subsequent request to retrieve access token fails with PKCE error.
Key info from the logs-
"ERROR: Exception in processing the tree
org.forgerock.openam.auth.node.api.NodeProcessException: Unable to get UserInfo details from provider
at org.forgerock.openam.auth.nodes.oauth.AbstractSocialAuthLoginNode.getUserInfo(AbstractSocialAuthLoginNode.java:338)
Caused by: org.forgerock.oauth.OAuthException: Unable to process request. {"error":"access_denied","error_description":"Not enough permissions to access Native PKCE protocol"}
at org.forgerock.oauth.clients.oauth2.OAuth2Client.lambda$mapToJsonValue$0(OAuth2Client.java:126)
at org.forgerock.util.CloseSilentlyFunction.apply(CloseSilentlyFunction.java:53)
at org.forgerock.util.CloseSilentlyFunction.apply(CloseSilentlyFunction.java:29)
at org.forgerock.util.promise.PromiseImpl.lambda$then$6(PromiseImpl.java:374)
at org.forgerock.util.promise.PromiseImpl.handleCompletion(PromiseImpl.java:536)
at org.forgerock.util.promise.PromiseImpl.setState(PromiseImpl.java:577)
at org.forgerock.util.promise.PromiseImpl.tryHandleResult(PromiseImpl.java:258)
at org.forgerock.util.promise.PromiseImpl.handleResult(PromiseImpl.java:208)
at org.forgerock.util.promise.PromiseImpl.lambda$then$6(PromiseImpl.java:374)"
LinkedIn API reference & OAuth2.0 -
https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context
P.S. Forgerock AM when integrated with Google using OAuth2.0 [PKCE] is working absolutely fine.
Any help will be much appreciated.
Thank you.
As per microsoft doc: https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow-native you need to contact linkedin team to enable PKCE for you and then the authorization URL for PKCE is different as well - https://www.linkedin.com/oauth/native-pkce/authorization
Related
It is known that PKCE Flow is good solution for SPA or native app, rather than the standard Authorization Code Flow.
However for the web app with server ("confidential client" as defined in RFC 6749), which one is more safe?
As mentioned in this post, "PKCE is all about verifying that the client that initiated the initial authentication request is also the same that uses the authorization code to get the real tokens."
How can Authorization Code Flow with PKCE be more secure than Authorization Code Flow without client_secret
However PKCE cannot involve client credentials (client_secret), which is used in the Authorization Code Flow to make sure the requester is the authenticate client.
So seems the standard Authorization Code Flow is more safe than PKCE Flow, for the web app with server (confidential client).
Nor sure is this unstanderding correct? Because we can see in the latest oauth2.1 draft it seems prefer PKCE, as it says "PKCE is required for all OAuth clients using the authorization code flow".
https://oauth.net/2.1/
Update on May-13 2021: Actually the oauth 2.1 suggests authorization code flow plus PKCE parameters, not using PKCE instead of authorization code flow.
Amazon and Microsoft have followed the suggestion in their spec.
https://developer.amazon.com/zh/docs/login-with-amazon/authorization-code-grant.html
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
Thanks all
You can refer to this document>> https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1 and references for more details.
The answer to your question is >> PKCE is safer than a normal Authorization code grant or any other grant.
I'm currently unfamiliar with the OAuth2.0 Authorization Code Flow and I've read many articles about it and currently I still don't know how to properly implement it. So far, what I know about the flow:
User Logs in using OAuth
User is redirected to the authorization server for authorization code
Callback for permission/scope
Redirected to authorization server for access token in exchange for authorization code
Redirect back to the client with the access token
Client uses access token to access resource server.
Right now, what I'm still confused is that where should the login validation come (Login of username - password)? Is it a separate validation before going to OAuth flow and once the user is valid, it should go back to the flow?
I have some resources that explain OAuth 2.0 using Google Sign in as an example. Let me try to rephrase it according to your question.
Let's use the example of a user logging-in to Intercom using "Sign in with Google".
The user presses the button "Sign in with Google". This will redirect to the identity providers /authorize endpoint (could be different for each provider) which go to their login page.
The user is redirected to Google's accounts page. If not already logged-in, the user can enter their Google email/password here.
Google redirects back to Intercom with an authorization_code (for example, it redirects to https://intercom.com/authcallback?code=XYZ...)
Intercom's backend server sends this authorization_code with the client_id and client_secret (from their project in google), and receive an access_token (usually to the /token endpoint)
Intercom can then use the access_token to access the user's profile from Google.
So to answer your question, the user can enter their email/password inside the OAuth provider's page. Keep in mind that OAuth 2.0 doesn't specify how the provider is authenticating the user. This means, that the OAuth provider can authenticate their users in different ways, like email/password, email magic-link, SMS OTP, etc. Your website is just supposed to trust the OAuth provider that they are authenticating the user for you correctly.
Some extra resources that would help you understand OAuth 2.0 more:
How to store the OAuth 2.0 access and refresh token in your front end
Picking the right OAuth 2.0 flow
login validation come (Login of username - password)?
OAuth 2.0 NOT an Authentication protocol
The OAuth 2.0 specification defines a delegation protocol
Any use of username - password is outside of OAuth 2.0 and you should be looking at Open ID Connect which is an authentication protocol built on top of OAuth 2.0.
Best current Practice for Authorization Code flow is to use PKCE on OAuth or OpenID Connect.
The usual solution is to externalise both OAuth 2.0 and Open Id Connect from your code by using a mature security library. When you're new to this type of security there is a learning curve. My resources will give you an idea of how it all fits together:
Code Sample
Tutorial Blog Post
The libraries you integrate depend on the technology stack you are using. The resources above are for a Single Page App and NodeJS API.
I have one requirement to integrate Servicenow with DocuSign using REST. We are using OAuth authentication using the grant type "JWT". We have created the OAuth entity and OAuth entity profile for DocuSign which we are integrating with ServiceNow. And also created the JWT Provider and JWT Keys for that tool we are integrating with.
We need to obtain consent from DocuSign we are integrating with. For this we need to access one URL provided by the tool which we are integrating with ServiceNow. When we access the URL, it was asking to login. After that it was not giving the consent instead it throws an error message "Failed to find OAuth initiator parameter in session".
I have verified all the details like JWT configuration and OAuth entity and OAuth entity profile and the details are configured correctly in ServiceNow. Still not able to resolve this error.
Please help me to resolve this error.
Thanks in advance!!
I have really hard time trying to understand mostly how should I implement my authorization flow. I think I have the authentication flow mostly correctly implemented using the technologies I've listed in the title. Here's what I want to achieve:
Basically I have a mobile app built using React-Native and I have made a restful API for this mobile app to use. I am currently at the point that I have implemented authentication using ADFS 4.0. My mobile app directly uses the ADFS endpoints to authenticate the user and I am able to receive the id_token and access token correctly from there. But here comes the part that I have no clue what to do next. Before I used openID, I had my own authentication and just an OAuth2 flow in my Spring REST Api and everytime I made a request from the mobile app to the API, I provided the access token in the headers, and used it to verify from the authorization server that the user is indeed authenticated and also received some crucial information about the user to use in my API. But now since I use OpenID-Connect and ADFS 4.0 for the authentication, I have the cruicial information I need in my API in the id_token. The question is, what exactly should i send to my API now from the mobile app, the id_token, access token or both? Given the access token to the userinfo endpoint at the ADFS returns the subject of the owner of the token. Like is there any way I could receive the users info using the subject or what exactly should I do. I've tried to research this subject a lot, but I am still very confused..
Send the access token to the API in the Bearer header. In the API, validate the token and, if required, do user info lookup. A Spring example of mine here if it helps.
Happy to answer any follow on questions ..
I am working on a mobile application that uses an api built with ASP.NET web api framework. We decided to use ACS alongside a custm STS as a mechanism to secure the api.
We are using a custom STS because we need to authenticate users against our own identity store.
The information flow is as follows:
Mobile app calls the custom STS with user credentials.
User is authenticated against our own identity store.
Once user is authenticated an authorization code is retrieved from ACS and used to retrieve an SWT access token.
Token is returned to mobile app.
Mobile app embeds access token in authorization header and fires request to API
HTTP module in API validates the access token and data is returned if the token is valid.
Everything is done over SSL as we are using oAuth 2.0.
The problem with oAUth 2.0 is that it is at risk from man-in-the-middle attack as the SWT token issued by ACS is a raw token and not encrypted in any way. It is however, signed using a 256bit symmetric key.
We are using swt tokens because we are using an http based approach and the token fits nicely into the auth header of an http request.
Microsoft have provided some ACS security guidelines in the following post:
http://msdn.microsoft.com/en-us/library/windowsazure/gg185962.aspx
we currently implement 2 of these as we check the issuer and the audience i.e that the token was issued by our trusted issuer (ACS) and that the token was issued for the correct audience (our api).
our scenario is based on the following article:
http://msdn.microsoft.com/en-us/library/hh446531.aspx
as such WIF is not used to handle incoming tokens. WIF is only used in claims processing.
given the above mentioned scenario is there anything else that we could be doing to improve the implementation we have to secure our rest based api?
any and all comments/criticism/suggestions welcome.
Thank you.
I think you're already taking the correct approach. The most important thing is to verify if the token is signed by ACS. Never share your ACS secret key with anyone else. If they don't know the key, they cannot forge the signature.
Also do not store confidential information in the token (such as password, credit card number, etc.). You should expect the token may be obtained by someone else, but no one can forge a token with the correct signature.