Is it possible or even advisable to use OAuth 1.0 to secure a RESTful web API without redirecting the user to a separate provider? - rest

I am in the process of building a RESTful web service using ASP.NET Web API, and I am considering using OAuth 1.0 as an authentication mechanism to secure the service. Our API would also be maintaining the credentials store and would therefore be the OAuth provider. Client applications using our API would be used by end users who would have to authenticate using a username and password, so I assume the client app is considered to be an OAuth consumer. The client application would make an API call to retrieve an unauthorized request token, then send along the user's credentials with the token to get an access token.
Ultimately, I could see other 3rd party applications wanting to access our application through my API, and they would use OAuth with the redirection with our application being the credentials provider.
Is this a viable way to use OAuth? Will something like DotNetOpenAuth support this scenario?

We have decided to implement OAuth 2.0, which supports various workflows, one of which includes a Resource Owner Credentials flow that allows the client to pass user credentials to the authorization server in exchange for an access token. This will serve our purposes.

Related

How to perform user registration and authentication between a single page application and a REST API with OpenID Connect

Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.

Pass SAML response from a Web App to the REST API for authentication?

We have a Web App using REST API. The REST API is based on Loopback and uses it's built-in token-based authentication. For the Web App we use forms based authentication over HTTPS, so the user has to enter his username and password which we then use to get access token from the REST API via POST /users/login endpoint.
One of our customers asked us to support single sign-on (SSO) authentication through SAML 2.0 and AD FS.
We configured our Web App as a service provider (Relying Party in AD FS) and managed to support SSO for it. The changeling part is the authentication between Web App and the REST API. The idea right now is to configure both Web App and the REST API as the same Relying Party and add new POST /users/saml-login endpoint to the REST API, so the Web App can send a SAML response to that end point and get an access token based on the claims specified in the SAML response. Everything else should work as it used to work before. Here is the flow I imagine:
Web App generates SAML request and redirects a user to the IdP login page
After a successful login the user is redirected back to the Web App with the SAML Response
Web App acts as a proxy and redirects the SAML Response to the REST API endpoint (POST /users/saml-login) where it is validated
If the SAML response is valid the API returns an access token based on the claims
Web App uses access token for further communication with the REST API same as before
Here is the question: Is it OK to implement SAML-based SSO this way? Do you see any issues or security considerations with this approach? Are there any alternatives?
I have read a lot of articles on the web and questions here on StackOverflow about how to use SAML & REST API together:
Propagate SAML Assertion Response/Security Context to downstream Services/Apps
REST API authentication with SAML
SAML and back-end REST service authentication
Attacking SSO: Common SAML Vulnerabilities and Ways to Find Them
None of them really helped me to confirm or reject the idea described above.
That sounds like a reasonable approach. I can't think of any security issues.
You're simply re-posting the SAML response internally within your application for processing. As long as you then perform the various security checks on the SAML response and assertion within your REST API, there shouldn't be any issues.

How to protect bearer tokens in a web app

I am trying to implement the Authorization Code flow described in RFC 6749 (OAuth 2.0) for a JavaScript-based application. I understand that I should use a web server back-end as a confidential client so that it can protect the access token and refresh token returned by the authorization server and not pass them on to the JavaScript front-end. Then all requests from the front-end to any protected resources go via the web server back-end, which attaches the access token to the request and proxies it on.
My question is how do I let the JavaScript front-end make use of these tokens in a secure way? I assume that I have to do something like set up a session on the web server and pass back a cookie that identifies the session. But this means that the JavaScript application then has a cookie that gives them the same privileges as if they just had direct access to the bearer tokens stored in the web server. How does having a web server to hold the tokens give extra security?
I understand that I should use a web server back-end as a confidential client so that it can protect the access token and refresh token returned by the authorization server and not pass them on to the JavaScript front-end.
No, it is a misunderstanding of the OAuth2 flows and goals.
Here is the OAuth2 main goal: your application (which can for instance be a JavaScript program running in the browser, a web server, both, etc.) MUST NOT need to know the user's credentials (most of the time a login/password pair) to access the service on behalf of the user.
Here is the way OAuth2 must be used to achieve this goal:
according to your needs, that is having a Javascript-based application running in the browser (i.e. not a node.js application), you need to use the OAuth2 implicit flow, not the authorization code flow. But of course, because your application is running in the browser, it will not be able to persist the credentials to access the resource offered by the service provider. The user will have to authenticate to the service provider for each new session on your application.
when your application needs to access the service provider when the user is not logged in, or when your application is able to persist credentials (because your application has its own credential system to identify its users), your application does not only rely on a JavaScript program running in the browser. It may rely only on a web server, or on both a web server and a JavaScript program that talks to this server. So, in those cases, you must use the authorization code flow.
So, as a conclusion, you have decided to add a web server to your application because you thought you had to use the authorization code flow. But in your case, you probably do not have to use this code flow, therefore you should select the appropriate code flow for your application: implicit code flow. And this way, you do not have to add a web server to run your application.
How does having a web server to hold the tokens give extra security?
This does not give extra security. Having a web server to hold the tokens is simply a way to let your application access the service on behalf of the user, in the background, when the user is not logged on your application.
While I agree with Alexandre Fenyo's comments, I just want to add the 2021 version. You should no longer be using the implicit flow as this is no longer considered secure.
For scenarios such as this where a JavaScript application has to handle tokens I would suggest using the Authorization Code flow with PKCE instead: https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce

OAuth Security with Pre-Configured Authorization

I have a scenario where a user has logged into to a web application (authenticated with OpenID Connect) and then needs to access data from a separate REST service.
The REST service needs to determine whether or not the user has permission to access the requested data, but if the user does have permission, then it should grant authorization to the web application without requiring the user to interact with the UI.
Essentially, what I need is a two-legged OAuth solution where the client/relying party is fully trusted but the user, who's already been authenticated, is not.
Going in, I assumed that OAuth could accommodate these requirements, but none of the grant types seem to match the requirements:
Authorization Code is the opposite of what I need, as the user is pretty much automatically trusted but the client is not, requiring that the user grant access to the client via a web form.
Client Credentials trusts the client (which is what I need) but does not give the service an opportunity to determine if the user has permission to the resource (user auth tokens are not passed to the service, making all requests essentially "anonymous").
ROPC (Resource Owner Password Credentials) would appear to be the only option, but requires the web application to know and possibly store the users' login credentials (which is untenable).
Is this a gap in OAuth? Or am I misunderstanding these grant types? If OAuth can't support this scenario, is there another widely adopted open standard that I've missed?
Of note: I only own/control the web application, while the customers (all of which are businesses) own/control both the authentication servers and the REST services. Therefore, a shared, non-proprietary standard is necessary so that our customers will know how to configure their services (IBM, Microsoft, whatever) and so that I'll know how to pass along any authentication tokens, etc.
I think this is possible using normal OAuth2 flows. You have your web application use the code authorization grant to get a token to call the API on behalf of the user.
Your web application makes the call to the API attaching the JWT token in the Authorization header. If the REST service determines the user does not have permission to access the resource, it returns a 401 Unauthorized HTTP response code.
Your web application handles the 401 response by going back to the authorization server and using the client credentials grant to get an access token to call the REST API on behalf of the client itself.
As both grants allow you to get a refresh token, you should be able to switch between access tokens easily.
If there is no trust relationship between the web application and the REST service, there's no way around using the Authorization Code grant since the user needs to be involved anyhow to allow the web application to make the call on behalf of the user.
If there is a trust relationship between web application and REST service you should be able to use the regular OpenID Connect flow to get an access token to the web application at login time that can also be used in calls towards the REST service.
You may pass on the user information as part of a JWT (i.e. a structured) access token that is signed by the web application itself or the OP; that would be OAuth 2.0 compliant. See https://www.rfc-editor.org/rfc/rfc6749#section-1.4 and May an OAuth 2.0 access token be a JWT?.

How to secure restful webservice with oauth?

I know that this question has been asked thousand times before but I am still unable to comprehend the answers properly. When I googled about this topic I found most of the people suggesting to use Oauth to secure Restful webservice.
I believe oauth is only applicable when you want third party applications to allow access to secured resources without sharing credentials of the user.
In my case I want to secure restful service which can only be accessed by our own developed mobile application. I am unable to understand that only for this purpose how I can utilize oauth to secure restful resources. My requirement is that for the first time user will enter his credentials into the application. Upon successful authentication application will receive a access token which then will be used to access secured resources.
Whereas in case of ouath user first of all gets redirected to the authorization provider website from mobile application (assuming mobile application as third party app) where he enters the credentials and then through a call back url the mobile application receives access token to gain access to secured resources.
I read Web API Design guide from Apigee in which they strongly recommends to use ouath. In fact Apigee App Services are secured using oauth and they are doing the same things which I need using oauth. As following curl command shows how to get access token using username and password as per apigee API Documentation.
curl -X POST -i -H "Content-Type: application/json" "https://api.usergrid.com/my-org/my-app/token" -d '{"grant_type":"password","username":"john.doe","password":"testpw"}'
My first question is that if I follow the same approach that allows third party application to get access token without any redirection and callback, will it result in violation of Oauth specification or not?
My second question is that can we use ouath for scenarios in which no third party application is involved and secured resource access is between application user and resource provider without any kind of confirmation.
This is definitely possible with OAuth2. With OAuth1 it was a bit more clumsy as you had to use '2-legged auth', which didn't feel all that natural, but in OAuth2 you can use one of these grants:
Authorization code grant
Resource Owner Password Credentials Grant