Spring Security OAuth 2 client customize User Info Endpoint Requests - spring

I am trying to implement a server client to authenticate to the Etsy API OAuth2 to get and manage store details.
Authentication works, but I am having issues with the user info endpoint call.
In the Etsy API the only 'appropriate' end point is getUser.
Two issues:
The getUser expects the Etsy UserId /v3/application/users/{user_id}, all the examples I have seen have a static uri. Is it possible to dynamically provide this?
The Esty getUser expects a GET request and as far as I can tell the default user info call is a POST. Can be configured?
Questions:
Does this require a custom ClientRegistration class to adapt the user info endpoint request to work with the Etsy API endpoint?
If so, is there an example starting point for implementing this functionality?
Details:
API documentation, Authentication:
https://developers.etsy.com/documentation/reference#section/Authentication
Note: The {user_id} is prefixed to the access_token in the authentication response. The response in theory should be parsed and the {user_id} used in the uri for user info request.
API documentation, getUser:
https://developers.etsy.com/documentation/reference#operation/getUser
Properties:
spring.security.oauth2.client.registration.etsy.client-id=REDACTED
spring.security.oauth2.client.registration.etsy.client-secret=REDACTED
spring.security.oauth2.client.registration.etsy.client-authentication-method=none
spring.security.oauth2.client.registration.etsy.provider=etsy
spring.security.oauth2.client.registration.etsy.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.etsy.redirect-uri={baseUrl}/{action}/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.etsy.scope=transactions_r
spring.security.oauth2.client.provider.etsy.user-info-authentication-method=form
spring.security.oauth2.client.provider.etsy.user-name-attribute=user_id
# Hard coded the user id, XXXXXXX, to prove the end point is reached, but the POST request fails (Etsy endpoint expects a GET)
spring.security.oauth2.client.provider.etsy.user-info-uri=https://openapi.etsy.com/v3/application/users/XXXXXXX
spring.security.oauth2.client.provider.etsy.token-uri=https://openapi.etsy.com/v3/public/oauth/token
spring.security.oauth2.client.provider.etsy.authorization-uri=https://www.etsy.com/oauth/connect

Related

Securing rest and actuator endpoints using custom token and http session

I have a spring boot app where the API #Controller endpoints are secured using a token that is contained in the http header. The token needs to be extracted from the header and validated against an internal cache to make sure it is valid. If the token is valid then the request can proceed to the controller and if it is not valid then it should return a 401 to the caller.
I also have another requirement to secure some of the actuator end points. When the user tries to use the browser to access the respective actuator endpoint, it will check for a user session if no session exists then the request is redirected to the spring login page. When they login I need to extract the username and password and validate using an external service. If valid a session can be created for the user and they can then use the hawtio endpoint. The session needs to store role based information so that when the user tries to perform JMX operations it will only allow them to perform the appropriate read only / write if they have the requisite role.
Any pointers regarding how you'd try and tackle this would be most welcome. I am unsure whether this is achieved by specifying addFilterBefore or addFilter and I don't understand how having authenticated the user for the actuator I go about creating a session that can be stored in the context and checked later on for subsequent requests.
Thanks

Is there any Spring boot Security specific solution to my needs?

I started using spring 4 mounth ago, I want to try any idea that I got and now I want to know if what I m trying to do is possible, if so is there any specific security mechanism that I m not yet aware of.
I successfully implmented a secured API that have Authentication and Authorization using the basic auth and ssl enabled, this API handles a cruds of pizza fabrication with it ingerdiants.
Now I Want to create another API that will handle billing of pizza so this api is going to use the previous.
this reuse principle got my attention is it possible to implement a security mechanisme in my second api that ask my first if my current user is loged in ?
the scenario in my head is looking like
user authentication and authorization in API pizza
user ask api bill to get a bill of a pizza (some request with headers ...)
the bill api asks the pizza api if the request source is already authenticated
pizza api answers if is authenticated or not
bill api store in memory the authentication state
By googling I m not sure if the spring security token based authentication is a solution.
NB: I m using only http Request there is no form or front end
High-level overview of the solution would be as follows:
Establish OAuth2 Server and Zuul gateway.
Service "A" authenticates against OAuth2 authentication server and calls service "B"'s Rest endpoint via Zuul gateway (i.e Zuul proxies call to Service "B") with OAuth2 token stored in the session and adds OAuth2 token in HTTP "Authorization" header on request.
Zuul looks up service "B" endpoint, propagates service "A"'s OAuth2 token using it's filter by inspecting Headers and and forwards call with the same token in "Authorization" header.
Service "B", which is protected resource, receives request, inspects headers and validates recived token against OAuth2 server.
You can also let Zuul automatically propagate OAuth2 access tokens further and authorize incoming requests against the OAuth2 service by using the #EnableOAuth2Sso annotation.

Which information gets sent in each API request using OIDC

I'm writing an API back-end that I want to use OpenID Connect (OIDC) to secure. I've been reading the documentation but I'm still a bit confused what process applies to each and every API request. The Open ID Connect code flow appears to be:
Which I'm fine with, as a one-time process. My back-end API sees an authorization code in the HTTP headers, and sends a request to the authorization server to get the id token. Assuming this validates OK, the data requested is returned in the API response.
But assuming the same user will then be making lots of requests to this API, what happens in subsequent requests? Is there some sort of session created in this mechanism? Do I continue to receive the same authorization code? Do I have to keep sending these back channel requests to the authorization server?
Or should I even output the JWT id token as a cookie? In this way I get the self contained id token coming back in future requests, with no need of a server side session, or further round trips.
I've been reading the documentation but I'm still a bit confused what
process applies to each and every API request
It is not the API that should follow OpenID connect protocol. It's the client that should do it.
My back-end API sees an authorization code in the HTTP headers, and
sends a request to the authorization server to get the id token.
Assuming this validates OK, the data requested is returned in the API
response.
Authorization code must be used by client application and not by the API endpoint. Also, authorization code must never be exposed to other entities.
You should use id token sent with OpenID Connect to authenticate the end user from your client application. To access API, you should use access tokens.
What to do in API endpoint ?
I think this is where you struggle. Your client application should send a valid access token to get access to API endpoint. From API endpoint, you can use OAuth 2.0 introspection endpoint to validate the tokens.
RFC7662 - OAuth 2.0 Token Introspection
This specification defines a protocol that allows authorized
protected resources to query the authorization server to determine
the set of metadata for a given token that was presented to them by
an OAuth 2.0 client.
Note that, OpenID Connect is built on top of OAuth 2.0. This means you can use anything defined in OAuth 2.0, including introspection endpoint. Use this endpoint to verify the access token validity.
What if you want end user details ?
OpenID Connect defines a user info endpoint
User info endpoint
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. These Claims are normally represented by a JSON object that contains a collection of name and value pairs for the Claims.
Here also, you use access tokens to get user information from this endpoint. The response will let you know the end user to which this token was issued.
Depending on your specific API requirement, you can do a token introspection or obtain user information from user info endpoint. Once that is done you may go ahead and authenticate a session. You might use both endpoints if you need all available information.
Alternatively(instead of sessions) your API can maintain an access token cache. This will remove the need to validate tokens in each an every API call. But be aware that tokens have expiration time. You must consider about token expiration if you are choosing this solution.
p.s - Client vs Resource server
In OpenID Connect and OAuth 2.0 terms, a client could be a simple web page, desktop application or could be even server hosted application.
client
An application making protected resource requests on behalf of the
resource owner and with its authorization. The term "client" does
not imply any particular implementation characteristics (e.g.,
whether the application executes on a server, a desktop, or other
devices).
Obtaining tokens and using them is the duty of the client application.
On the other hand, resource server contains protected resources,
resource server
The server hosting the protected resources, capable of accepting
and responding to protected resource requests using access tokens.
Resource server exchange it's resources to access tokens. If we match the same scenario to basic authentication, access tokens replaces username/password sent with authentication headers.
Typically you'd secure a (pure) API with OAuth 2.0, not OpenID Connect. The Client accessing your API should obtain an OAuth 2.0 access token and in order to do that it may choose to use OpenID Connect to obtain that token. That is all independent of the API, which will only see the access token. The API (or Resource Server in OAuth 2.0 terminology) is not depicted in your diagram.

Spring Security to Validate login RestAPI

I know this question asked many times but I did not get answer that I required.
I want link that can help me to create a spring security framework, In which I donot whant login form validation.
It should be done by login RestAPI. I just hit url like-
http://localhost:8080/login
post request containing username and password and it return json response with sucess or failure status
if sucess I would be able to hit secure API Requests.
I am using spring and spring security since 1 and half year with spring security to develop rest API I use below technique for user authentication
Follow below steps
Allow to access http:// localhost:8080/login for all user
User will pass username and password in body
Authenticate user with database entry
create access token and send back to response
using this access token user with interact with secure API.
I will provide source code if you need.
I suggest you to try with Basic Authentication. I believe Rest services are mutual contract between the consumer and provider, so re design your service to access the basic auth header. Your client need to pass the base64 encoded value of username:password, Your service should get the header value and decode you will get the original data back, Check against your backend storage (Ldap or DB).
More about basic authentication . BasicAuthentication

Laravel: API with OAuth 2.0

I am currently developing an API that I plan to secure using oauth2.
I have chosen: https://github.com/lucadegasperi/oauth2-server-laravel/
I have managed to secure the endpoint (using before=>oauth in my api routes) by following the installation guide but I am at a loss as to how am I gonna be able to authenticate and access the endpoint.
I do understand that you will first need to request an access_token by sending a client_id and client_secret but what I don't get is where do I set those on the oauth server?
I see the oauth controller has endpoints for these like:
http://somedomain.com/oauth/authorize
http://somedomain.com/oauth/access_token
But I am clueless with what to do with them. I only managed to arrive at the conclusion that it needs a client_id, client_secret, and stuff about scopes.
Where can I set these values for the api client to use?
Thank you for your help in advance.
I don't know Laravel, but in general, the authorization endpoint (in your case, http://somedomain.com/oauth/authorize) behaves as described in RFC 6749.
The specification defines four flows. If you use Authorization Code Flow among the flows, you should access the authorization endpoint with the following request parameters.
response_type=code (required)
client_id={your-client-id} (required)
scope={space-delimited-scope-names} (optional)
redirect_uri={your-redirect-uri} (conditionally optional)
state={any-arbitrary-string} (optional)
For example,
http://somedomain.com/oauth/authorize?response_type=code&client_id=your-client-id&scope=profile+email
The authorization endpoint generates an authorization code and returns it to your browser.
The next step is to access the token endpoint (in your case, http://somedomain.com/oauth/access_token) with the authorization code which has been issued from the authorization endpoint. Like this,
POST
http://somedomain.com/oauth/access_token?grant_type=authorization_code&code=issued-authorization-code&client_id=your-client-id&client_secret=your-client-secret
Anyway, I recommend you read RFC 6749.

Resources