Linkedin "Scope" Variable not set - spring-social

I'm having trouble setting up a connection to Linkedin Api using Spring Social.
I am passing the "scope" variable "r_emailaddress" as a hidden field with the form to retrieve the email address but it's not working - I don't see the email_address permission like you do here. https://developer.linkedin.com/sites/default/files/gp-dialog.png
I am following the Spring Social Showcase Application Example. I should add, the Social Application there is no hidden scope field.
It works fine with Facebook.
Form
<form name="linkedinin_signin" id="linkedin_signin" action="${linkedin_uri}" method="POST">
<input type="hidden" name="scope" value="r_basicprofile, r_emailaddress" />
<input type="image" src="${linkedin_img_uri}" />
</form>

It is correct that LinkedIn is an OAuth 1.0a provider and that the "scope" parameter is non-standard with regard to OAuth 1.0(a). Therefore, Spring Social did not recognize the scope parameter for OAuth 1.0(a) providers.
However, you may be interested to know that yesterday I pushed a change to Spring Social that will allow any arbitrary parameter to be passed along to the request token URL and the authorization URL...including the "scope" parameter. This change, being relatively new, is only available in the latest 1.1.0.BUILD-SNAPSHOT builds, but will soon make an appearance in 1.1.0.M2. This should address your need.
You may also want to look at the Spring Social Showcase example, as it now uses the "scope" parameter to request "r_emailaddress" scope when a user connects to LinkedIn.
I'd appreciate any feedback you have on this change, preferably as comments to https://jira.springsource.org/browse/SOCIAL-349 or in the Spring Social forum at http://forum.springsource.org/forumdisplay.php?82-Social. (I do not monitor questions on StackOverflow nearly as often as I do on the Spring Social forum.)

I've had the same issue with LinkedIn. Here is what I did to resolve it:
instead of
final OAuth1Parameters params = new OAuth1Parameters();
params.set("scope", "r_emailaddress r_basicprofile");
I had to send a map with the fetchRequestToken
final MultiValueMap<String, String> mvm = new LinkedMultiValueMap<String, String>();
mvm.add("scope", "r_emailaddress");
mvm.add("scope", "r_basicprofile");
inRequestToken = oauth1Operations.fetchRequestToken(redirectUri, mvm);

LinkedIn is recognized by SpringSecurity as OAuth1 provider. OAuth1 does not support "Access Token Scope" feature. So your scope parameter is silently ignored. Actually LinkedIn uses non official OAuth 1.0a protocol version that has support for scopes. As a workaround you can try to override some SpringSocial classes and send scope parameter to LinkedIn. See this thread.

The oAuth1 API of linked in doesn't support the scope parameters at all, you must use oAuth2 - http://developer.linkedin.com/documents/authentication - to be able to get the email address

Related

Set and update Keycloak/OpenId-Connect Claims in Client application

I'd like to know if and how it is possible to set and update Keycloak (OpenID-Connect) AccessToken or IdToken attributes (so called Claims) by a client web application, after successful authentication.
The use case is to add specific user-attributes (e.g. number of pets, hair color, favorite car, etc.) to the Access- or Id-Token, while the user is logged in to our web application based on a Vue.js Frontend and a SpringBoot Backend, mainly exposing REST Services to the Frontend.
A second web-application, also using the Keycloak Token for user authentication/authorization (Single-Sign-On feature) should be able to read the user-attributes added by the first web-application to the Token.
Even I'm afraid that adding and changing of Token payload is not allowed by architectural design of OpenId-Connect, I nevertheless hope it will be possible anyhow.
Token-attributes are implemented as 'Claims' in OpenId-Connect. And Keycloak supports 'Claim' mappings during the authentication process (set by static mappings on Keycloak server as well as by code that runs on the Keycloak server).
The appropriate methods to set and get Claim key-value pairs are mentioned by the following articles:
How to create a Script Mapper in Keycloak?:
token.getOtherClaims().put("myClaimName", "claim value");
Include user locale to the Keycloak ID token:
Map<String, Object> otherClaims = token.getOtherClaims();
if (otherClaims.containsKey("myClaimName")) {
String claimValue = String.valueOf(otherClaims.get("myClaimName"));
}
For the case changing of Token payload by Keycloak clients is not allowed by architectural design, I appreciate any suggestion on best practices to hand over dynamically added user-attributes from one webapp to another webapp, having the same Keycloak Access- and/or Id-Token in common.
Yes, changing of token payload by user application is not allowed/possible by architectural design. App doesn't own private key, which is required to create proper token signature, when you change payload.

Using access token to get additional user info from cognito?

I have have integrated a OAuth 2.0 Resource Server in my spring boot application using JWT and issuer URL as describe here: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver I am integrating against AWS Cognito service and everything is working, however I am missing the information I want.
I am currently receiving the Access Token from the React front-end which does not contain any custom attributes for the user, only groups. As stated by the documentation here: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
Is there a way to get the custom attributes through the use of an access token, through a callback or something to Cognito?
Alternatively I could receive the ID token directly however after browsing around this does not seem like the best practice? I am pretty new to implementing OAuth 2.0 so I am not sure about all the pros and cons.
The /oauth2/userInfo endpoint will provide you information about the authenticated user.
https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html

Azure B2C Access Token NULL Spring OAuth 2.0

I am trying to get a custom web application to work with Azure B2C OAuth and the Spring OAuth2.0 framework.
The authentication leg comes back fine and I receive a JWT token. When the request for a token occurs afterwards I get the following error:
java.lang.IllegalStateException: Access token provider returned a null access token, which is illegal according to the contract.
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:223) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
...
From some debugging of the spring code I can see the token is expected to be called access_token as seen in the OAuth2AccessToken class. From looking at the B2C tutorials their token is called token_id. Furthermore the applications.yml config I have for my spring application has a field called tokenName. Surely this should be used to pick up the token name field instead of the hardcoded static variable as above.
Am I missing something and is there a solution to my problem. Can I override the token name field used by the spring OAuth framework?
I'm going to go ahead and post this as the answer.
I started with the Spring tutorial, and made some modifications to it. For a working example, see the public github repo: https://github.com/Pytry/azure-b2c-oauth2.git
To properly parse the token received you will need:
A custom implementation of an AccessToken that will parse the JWT, pulling and setting variables as required by spring security. I extended DefaultOAuth2AccessToken and added this parsing to a private method called by the constructor.
If you are going to verify the RSA signature using the public keys, you will need a custom JWT object so you can access the header information. I chose to extend springs JWT, and add some parsing on creation to access the header. It may also be useful to have some custom Pojos for parsing the returned meta data and rsakey information into.
An extension of the JwtAccessTokenConverter, with an overridden "decode" method. Azure does not give a "user_name" nor a "client_id" in the returned id_token, so you need to add those. I also included some logic in the super class that I found suefull (such as converting strings to int/long when appropriate).
A custom UserDetailsManger to override the default in memory one. This can either retrioeve user information from the GraphAPI, or it can load it from your user repository. I actually did not create either of these, and instead used the default in memory service, but injected it into the token converter; then whenever a user was properly authenticated, I would add them to the managers store, or update them if they already existed.
There are a few things I have not done yet.
RSA verification is not being done. Any help on this is appreciated.

Simple Web Token (SWT) Authentication in Web Api 2 OData endpoint

Ok, the situation is this.
We already have an existing ASP.NET MVC 5 site with Custom Forms Authentication, Logon, Registration etc with a custom database for roles and profiles already implemented.
We now are adding some new functionality to the MVC site and we decided to use Web Api 2 OData 3 endpoint which lives in another domain. The Web Api currently doesn't include any authentication but we need to be able to map the requests to a certain user to get his roles etc from the backend. The MVC and API sites use the same backend.
What we would like to accomplish is, that when the user logs on in the MVC site, the MVC site calls the Web Api server-to-server with the user's credentials and receives a token that the client can then use to call the web service with.
When API receives a request with the token, it can then map the request with the user in backend and do authorization.
As far as I understand it, Simple Web Token (SWT) could pull it through. But considering the environment, .NET 4.5.1 / Web Api 2 / OData 3 with Entity Framework in Azure Web Role, I started thinking is this SWT something I should really use or if there is any NEW technologies recently published that could easily pull this through. I don't want to add any unnecessary 3rd party dependencies to the project if the .NET stack already contains something like it.
So, what would be the simplest way of pulling this kind of authentication through without adding unnecessary dependencier to the project.
The solution we are looking for, is only temporary meanwhile we redesign our authentication scheme. So we are looking for something really simple to implement that works with least dependencies that need to be removed later on.
I'm using this in a project I'm currently working on. I use the OAuth 2.0 OWIN Middleware component that ships with Web API 2.0 (if you add a new Web API project with Authentication enabled, it includes the base infrastructure).
You would use the Resource Owner Password Flow as defined in the OAuth 2.0 specification. Basically you request a Token from the Web API OWIN Middleware sending:
client_id - identifies your MVC endpoint
client_secret - identifier your MVC endpoint
username
password
And in response you get a bearer token. The token generating is based upon a claims principal, the OAuth middleware component has predefined hooks for adding claims. This token now needs to be added as authorisation header to each response. On the MVC side you might add this to session so that it's always available to make backend API calls in the context of the user associated with an incoming HTTP request. If you're using WCF Data Services Client, you'll need an authorisation service/manager or similar that you can hook into OnRequestSending and OnResponseReceived events, so that you can insert that bearer token into the HTTP headers.
You can customise the OAuth Middleware component as you need to quite easily, it took a bit of time to figure it out as it's not too well documented, but downloading the Katana source code did help a bit as the source code does have some good documentation.
The nice thing about it all is that you simply need to enable HostAuthenticationFilter and add Authorize attributes on the Web API side and it's ready to go. You can get access to the claims principal object and use claims as identifying pieces of information for your user - e.g. identity, roles, other attributes etc.
To get started, look at http://www.asp.net/vnext/overview/authentication/individual-accounts-in-aspnet-web-api
Also as a wrap, I did consider the use of JSON Web Tokens (JWTs) as there is an OWIN library available for generating and parsing these. The use case here would be that you authenticate, get a JWT back, and then use the JWT to get an OAuth 2.0 bearer token. The JWT is useful if you want to move authentication elsewhere, or if you want to get additional information about the user at the MVC side of things.

Requestign addional permission to linkedin via ProviderSigninController

I'm using spring social to login using linked-in, I need to request for additional permission, I do with scope variable for other providers (facebook, twitter) it just works fine but for linked-in it does not, since Linked-in uses oAuth 1.0 it's not supported - is what I could see in other forums, I'm sure there is a work around could you suggest one ?
<form id="linkedin-login" action="signin/linkedin" method="POST">
<input type="hidden" name="scope" value="r_fullprofile" />
</form>
Thanks in adavance.
Hi I'm answering back to my own question, that might be some help to others as well.
Linkedin uses OAuth 1.0a. OAuth1.0 officially does not support scoping of authorization, It's only Linkedin extension to OAuth1.0, since Spring social follows the standard of OAuth1.0, the scoping does not come out of the box, it needs a work around of overriding / adding new ProviderSigninController, connect controller and Connectsupport (getAccessToken method) classes.
More details: http://forum.springsource.org/showthread.php?129684-Linked-In-member-permissions

Resources