Spring Security OAuth2: Client as javascript application - oauth-2.0

I am using client_credentials grant type in my spring boot application. In client_credentials grant_type the client makes a request to the token endpoint. If the access token request is valid and authorized, the authorization server issues an access token.
localhost:8181/OUTPOST/oauth/token?grant_type=client_credentials&client_id=myClientId&client_secret=secret
The problem is my client is a javascript application. Client application wont be able to securely store the client credentials, so there is no point is having client_secret.
Implicit, password and Authorization code needs user details for generating token. But i dont have any user, i just need to validate my client application.
Which grant_type should i use to support my requirement?

The implicit OAuth2 flow is wat you are looking for. Details from the OAuth2 spec: https://www.rfc-editor.org/rfc/rfc6749#section-1.3.2

I don't think what you are asking is really valid. It is not possible to authenticate a JavaScript client securely via OAuth2 without user credentials. This would mean that everyone that can access the JavaScript app would be authenticated.
If you want to restrict access to this app without user credentials, it might be better to add network level policies instead, like IP range whitelisting.

Related

Why client authentication is NOT mandatory with Authorization Code Grant and Implicit Grant in OAuth2.0

According to RFC6749 Chapter 4.1.1: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
In the specification of Authorization Request for Authorization Code grant,
Only client_id is required for Authentication. Since client type could be public, then that means anyone can get the Authorization Code, and then use it in Access Token Request - https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3. Here you only need to supply client_id (Which is public), Authorization Code (Which can obtain with NO authentication), redirect_uri and grant_type (Not for authentication/authorization purpose), and then you will be able to obtain an access token!
My question is, why there is NO any mandatory authorization/authentication procedure for this type of grant, then what is the purpose of having this type of grant? Same thing in Implicit grant.
The client authentication is not mandatory only for the clients that are registered as public client like Mobile Native Application. The Mobile Application can not hold client secret securely, hence it is not mandatory in authorization code grant and implicit grant. The client application like web application which can hold client secret securely in the server, such clients should be registered as confidential client. The clients that are registered as confidential client should present both client id and secret for client authentication.
OAuth2 server issues an authorization code after user authentication and after user approving consent with delegating rights to the client (identified by client_id). The auth code is then sent as a parameter to a client's registered redirect URI. So I don't know what you mean by "anyone can get the Authorization Code".
Public clients should be used with PKCE OAuth2 extension. Which serves as a one-time password. So even if an auth code get stolen, it cannot be exchanged for tokens without knowing the code_verifier parameter of the token endpoint.
If an attacker creates a malicious application using someone else's client_id (pretending to be the client), the auth code will still be sent to the client's redirect URL. If the attacker gets hold of this URL handler, then it's probably a problem beyond the scope of the OAuth2 protocol.

Can I authenticate with OAuth Authorization server by passing username and password in Authorization header?

In case of OAuth 2.0 authorization code and implicit flow cases, on hitting the Authorization Url user is redirected to OAuth providers login page.
To avoid showing up the OAuth providers page in my application, can i make user to enter username and password in text fields and pass them as Authorization header of authorization Url and get back access_token from OAuth provider and use it for further requests ?
Is it legal, valid and feasible ?
Is it legal, valid and feasible ?
No. Not with the flow you are using right now. Implicit flow is not built for this purpose, so you cannot do it.
But, OAuth 2.0 provide you a dedicated flow for your requirement.
4.3. Resource Owner Password Credentials Grant
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged application.
As described in protocol, in this flow, your end user(resource owner) provide their credentials to client application. Client application call token endpoint with resource owner credentials to obtain access tokens.
Flow overview (From RFC6749)
Token request request (From RFC6749)
As specification mention, this flow is there to support old systems which are unable to fully utilise OAuth 2.0. For example clients which use basic authentication.

Why does authorization grant flow skip the authorization code just return an access token?

I'm learning about O Auth 2 from here
I was wondering in the step of "Authorization server redirects user agent to client with authorization code", why doesn't the server just give the access token instead? Why give an authorization code that then is used to get the access token? Why not just give the access token directly? Is it because there there is a different access token for each resource so that you need to go through O Auth again to access a different resource?
The authorization grant code can pass through unsecured or potentially risky environments such as basic HTTP connection (not HTTPS) or a browser. But it's worthless without a client secret. The client can be a backend application. If the OAuth2 server returned a token, it could get compromised.
There is another OAuth2 flow - the Implicit flow, which returns an access token right after the authentication, but it's designed mainly for JavaScript applications or other deployments where it's safe to use it.
If a malicious app gets hold of the client id of your app(which is easily available, for example one can inspect the source), then it can use that to retrieve the token without the use of the client secret. All the malicious app needs to do is to somehow either specify the redirect URI to itself or to tap into the registered redirect URI.
That is the reason for breaking the flow as such. Note, when the client secret is not to be used as in SPA (Single Page Apps) or Mobile Apps, then PKCE comes to the rescue.
There is a reason for breaking up the authorization flow so as to keep the resource owner's interaction with the authorization server isolated from the client's interactions with the authorization server. Therefore we need to have two interactions with the authorization server. One in which the resource owner authenticates with it's credentials to the authorization server. And another where the client sends in it's client secret to the authorization server.
Please also see PKCE that deals with SPA (SinglePageApp)/Mobile apps.

OAuth2 Login (Not Authorization)

I have implemented an OAuth2 register workflow (in Java) according to rfc6749
I'm using GitLab as OAuth2 Provider.
After the user granted access to my application for his account, I get an OAuth Token (along with refresh token and other stuff), I am able to make API requests on behalf of the user, so this is working fine.
This way I can get the users e-mail adress which I use to create an internal user.
My questions are:
Is it practice to issue a token that is generated by my application for the user (along with the OAuthToken) or should I just use the token that has been issued by the OAauth Provider? (My App also has local auth with bearer tokens). This token will be used for further API - CLIENT communication (stored in Angular2 local storage as bearer)
How to do login only? When a OAuth User accesses my web service, how do I know that this user is a OAuth User and which OAuth Token belongs to him? How can the user login without providing e-mail or password? (The user has no password) I guess I have to redirect him to the OAuth Provider again, but I don't want my user to grant access everytime he logs in.
Answer 1:
Though you can use the token provided by OAuth provider, you SHOULD NOT use it considering the risk that may arise exposing it to the public.
Instead you should securely save the token provided by OAuth provider into the database and use another token for authentication of further api calls. (you could use JWT)
Answer 2:
There are two types of systems
Which always uses OAuth provider for identifying user. (Ex. Tinder)
Which provides both OAuth Login and Traditional login/signup. (Ex. Quora, Instagram)
If you want your application to follow 2nd approach, you should ask the user to create password for the first time when the user logs in using OAuth provider.
This will allow the user to log into your application by both methods, traditional as well as OAuth
To identify users of your application, you should either use HTTP session or issue your own tokens. Do not use tokens generated by the OAuth2 provider - they are meant to be used just by your backend (in role of an OAuth2 client).
To use an external authentication in your application, you probably want to use OpenID Connect, not a bare OAuth2. OpenID Connect extends OAuth2 and it's meant for authentication instead of the rights delegation. Then you use an implicit flow (instead of authentication code grant) with scope=openid, your frontend app (HTML+JavaScript) gets an ID token signed by the OAuth2 provider. After successful signature verification, your backend can trust that the client is the one described in the ID token (in its "sub" field). Then you can either keep using the ID token or generate your own token.

OpenId Connect logout for stateless SSO

I am trying to implement OpenId Connect for SSO in one of my projects. However, I am a bit struggling with the case where I would like to validate OpenId JWT token on Resource Server side to make it stateless. If user tries to logout, authorization Server will know about the user logout (Accordingly OpenId Connect Session Management spec). But how should Authorization Server tell Resource Server that the user's token is not valid anymore? It is a case when user after log out out goes to Resource Server with his OpenId token and gets access. That is weird and I could not find any solution across Internet. Please help me to organize stateless security with central logout.
You can use Token Introspection endpoint to determine whether the access token passed is valid or not. The resource server can make a call to OP's introspection endpoint to validate the token before giving access to the resource. In order to effectively validate the token, the resource server should :
Be a registered client with OP and have Same / similar Scope as SPA app (Implicit flow app) to validate the scopes passed to it and
Have access to Introspection endpoint
The are more details in the above linked Spec for further understanding.
P.S. The answer that I wrote earlier has some other relevant references.
you can use jwt bearer flow, where you can pass ID token/Assertion token to OP in order to generate access token.

Resources