0
votes

I would like to use OAuth to authorize users (identified by username, password) on an intranet, but I don't quite understand how to use OAuth to fulfill my needs.

My main concern is to prevent the backend (Client), to collect the user's passwords and the frontend, to receive the access-token.

If I use the Password Grant Type, only the frontend could collect the users credentials, however as there is no redirection nor authorization code for this Grant scheme, the frontend will also get the access token which can therefore be stolen.

Also, with this Password Grant Type, the frontend have to provide both the client_id and client_password which is only known by the backend.

How can use OAuth with Password Grant in this situation?

The use-case

I am writing an intranet platform that should accept users from an Active Directory server. The naive solution is to use a form such as:

<form method="post">
  <input type="text" name="username" required>
  <input type="password" name="password" required>
  <input type="submit" name="login">
</form>

Therefore the backend can verify the received credentials with the Active Directory server. But, this is a very insecure solution because the backend could collect the user's passwords. As I am writing the application, this is very tempting :(

So, I would like to setup third-party OAuth server out of my control in order to use this form instead:

<form action="http://oauth.company.com" method="post">
  <input type="hidden" name="redirect" value="http://intranet.company.com">
  <input type="hidden" name="grant_type" value="password">
  <input type="hidden" name="client_id" value="badbeef">

  <input type="text" name="username" required>
  <input type="password" name="password" required>
  <input type="submit" name="login">
</form>

With this solution, only the frontend will see the password, but as any user could check the source code, this prevents me to try to grab their passwords because I would be too much exposed.

With the OAuth Password Grant scheme, I have two problems:

  • The frontend must be aware of the client_secret.
  • The frontend will receive the access token.

So I would like either solutions:

  1. The frontend get an authorization-code that will be then transmitted to the backend
  2. The Authorization Server personally informs the backend of the access token.

The wished authentication flow

From the Frontend, the Resource Owner enters his credentials that are sent to the Authorization Server, thus the Client does not know the Resource Owner credentials.

POST /oauth/token HTTP/1.1
Host: oauth.company.com

grant_type=password
&username=jdoe
&password=secret
&client_id=intranet-id
&state=123
&redirect=http://intranet.company.com/auth

The Authorization Server grant the user and sends this back to the fontend:

HTTP/1.1 302 Found
Location: https://intranet.company.com/auth?code=g0ZGZmNjVmOWI&state=dkZmYxMzE2

Then the backend requests the access-token with the received code:

POST /oauth/token HTTP/1.1
Host: oauth.company.com

grant_type=????
&code=g0ZGZmNjVmOWI&state=dkZmYxMzE2
&client_id=intranet-id
&client_secret=intranet-secret

Then it receives:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
  "scope":"create"
}

From this point, the backend redirects the frontend to the intranet portal.

1

1 Answers

1
votes

The Resource Owner Password Credentials grant is a deprecated flow only defined for migration purposes. It is surely not to be used with Javascript applications for the reasons that you listed. Use the Implicit or Authorization Code grant in this case where the application redirects the (full) browser to the Identity Provider and the Identity Provider can authenticate the user without your Client being involved.