The correct OAuth2 flow for public clients

I read here regularly when the stack overflows, but this is my first question.

I am developing an authorization server using OAuth2 specifications. And I was just stuck on how to provide third-party authentication when using a password stream. I read a lot of forums and this is what I got:

  • Javascript Single Page Clients

    In this blog post by Alex Bilbie, he claims that to avoid the client_secret problem we should simply:

    Its simple; proxy server of all your API calls through a thin server component. This component (lets just call it a proxy here) will authenticate ajax requests from a user session. Access and update tokens can be stored in encrypted form in a cookie that only proxies can decrypt. The client credentials of the application will also be hardcoded to the proxy so that they are not publicly available either.

    But now, this proxy can be accessed by someone personifying my angular application. And then I came across this blog post by Andy Fielder: How secure is the OAuth2 Resourc owner password stream for individual pages . He relies heavily on CORS to avoid impersonating a JS client.

    Is it good to use both approaches to protect my JS application?

  • Native applications (desktop and mobile)

    In the case of mobile applications, I found only Code authorization cases and implicit flows. This is not what I want, since redirects will compromise the user interface. So my thoughts on this are:

    I will use the ROP stream and then register the client using the client_id generated for this particular installation and attach it to the user account, getting access_token and client_secret as the response. Any other token request made by this client MUST have these credentials (since client_id is installation specific, I can verify that this client is already authenticated). Thus, if someone uses credentials to impersonate a client or even register a dummy client, I can accept mesures to deny user and client access.

I know that this can be excessive, and I also know that some of these issues do not shun anything. I just feel that it is my job to protect my API as much as possible.

I would really appreciate your thoughts on this! Do I really think? Should I just use the concept of "public client" and continue?

Thanks to everyone and happy coding!

+7
javascript security authentication mobile
source share
1 answer

First of all, this problem is not a general priority, since most applications are developed first from the website, and then with the API. This is probably the reason because no one knows how to handle the first clients with oauth2, because everyone has other ways to do this, and oauth2 is only necessary to provide the user with access to third-party applications.

Even if you created the oauth2 authorization server only for your first client applications (thinking of one authentication mechanism rather than developing many), you should try to develop an authorization code or implicit grant types. You will understand that you need a way to verify that the user has actually registered .

Two common methods:

  • user session (based on cookies)
  • user access from localStorage (based on javascript)

In any case, you need to check the security of your application, the user session is vulnerable to CSRF, localStorage is vulnerable to XSS. There are many articles on how to protect your site from both, so I will not offer anything here, you just need to know that they exist.

Now that you have chosen your authentication method, we can begin to consider:

Applications for individual Javascript pages

  • Proxy
    Having a proxy server that filters all requests, in my opinion, looks like a door with keys always inserted. It is useless to even build a door. However, for session-based authentication, this is the only way to do this. Allowing session authentication in your Rest API will open for CSRF security issues, so you need to have a proxy level that receives the user's session, retrieves the access token from the session, and executes the request to the Rest API, adding the Authorization header.

  • CORS
    With this method, you need to save the user's access token in localStorage, because the token is retrieved directly from the Js client.
    Using CORS, you are sure that other websites cannot fulfill requests to your Rest API from a browser. But your first client must be publicly available (i.e., it does not have client_secret ).

Native applications (desktop and mobile)

In my first application, I tried using the same mechanism that you suggest to provide auth flow. However, this type of mechanism requires a unique definition of each user client. This is not possible on iOS for immunity reasons , and with some probability it will be denied in future versions of Android. Therefore, you should rely on the public client and add only client_id in your own application code.

Does this mean that your own application client / your js client can be impersonal?
Yes, and there is no way to prevent this with the credential password of the oAuth2 resource owner .

The main reason for this is that oAuth2 is not for authentication, only for third-party authorization, and this type of grant was added only for certain third-party applications that are trusted enough to directly use the user password . Here you can read more about this argument here and here .

In the end

You still need a way to authorize your user, and I think the best you can achieve using oAuth2 is what Auth0 did. Basically, Saas manages your users an oAuth2 + OpenID server, so you always manage by its users, as a third-party application, and everything works fine.

In fact, you can see on this page that they offer to use a browser-based login form for mobile applications, since they will be beheaded by anyone who decompiles your application, but if you wrap it in an authorization code stream, it works great.

+1
source share

All Articles