Why should /oauth/authorize be secured? - spring-security

According to http://projects.spring.io/spring-security-oauth/docs/oauth2.html:
N.B. the Authorization endpoint /oauth/authorize (or its mapped
alternative) should be protected using Spring Security so that it is
only accessible to authenticated users.
Why is that? It doesn't sound right that an endpoint that will require an authorization grant to exchange for an authorization code should be secured. It's like a login page for a login page, specially when Authorization grant will be through resource owner password credentials.

oAuth2 authorization works in two steps:
User authenticates using their credentials
User grants application X the authority to use their data
Step 2 happens on /oauth/authorize and step 1 happens elsewhere in your application (most likely through a form-login backed by Spring Security).
If you don't protect /oauth/authorize you will end up granting authorization without authenticating the user (or you won't because without an authenticated session you probably have no idea who the user is).

Related

Open ID Token vs Oauth Token

I am new to OAuth and OpenId, and after reading multiple pages and information I still do not feel confident at all.
My goal would be to create an iOS Application that communicates with my BE. I need the iOS app to authenticate the user to access their resources.
Reading about OAuth, the solution seems to be straight forward. Just use the Authorization Code Flow with PKCE to make the App have an Access Token. This way I am authorizing my iOS app to access user's data. When the iOS app calls https://example.org/user with the access token, the resource service (my BE server) can get the access token and call the introspection API to know to which user the access token is bound to, and return the correct user data. Since authorization needs authentication to be made in the first place, having the access token would mean that the user is (or at least was) authenticated.
First thing that confuses me: According to the OAuth specs, OAuth is not an authentication protocol, but still the protocol authenticates the user using the user's credentials. Why is OAuth asking the user for credentials, instead of relying on another protocol/flow for user authentication? Such protocol would just acknowledge to OAuth that the authentication was successful.
This first issue made me start reading about Open ID Connect specification and the ID Token. This token would be received by the iOS app. What is the iOS App supposed to do with it? I can already get the user information calling the /user endpoint. How would this ID Token be an advantage?
tldr
Access token (OAuth 2.0) - authorize against OAuth protected
endpoints.
ID Token (OIDC) - authentiation by client application.
Authorization server authentication - It's there to detect
authenticity of end user involved in both protocols (pseudo
authentication from client application perspective)
OAuth is not an authentication protocol, but still the protocol contain a step to authenticate the user using the user's credentials
Correct, OAuth is not an authentication protocol. It is for authorization, which means identifying there are correct access grants to access a protected resource (protected resource ? ex:- An API, A photo stored in a backend).
So why you see end user login dialog ? Well that is the job of authorization server. It authenticate end user to be known by it and then issue the access token to client (client == in simple terms the application which end user uses). So yes there is an authenitcation happening, but this is not applicable to your client application or protected endpoint. One can define this as an pseudo authentication.
OpenID Connect - For authentication of client application
In the original RFC (RFC-6749), OAuth 2.0 was defined as a framework. OpenID Connect was an extension that built on this framework. What it provide ? Well as you found out, it introduce the ID Token. And ID token is issued by authorization server to be consumed by your client application. It contains end user identity information in JWT format. By validating integrity of this token, your client application can authenticate the end user. And access token ? That's there to used against protected endpoint. It doesn't say anything about end user to client.

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.

How to not have consent page in OpenID Connect Authorize Endpoint for Resource Owner?

When I had resource owner grant type, I never needed to deal with the Consent Page but now I am trying to create SSO for my systems using OpenID Connect and I am very confused. /authorize endpoint always shows consent form for public apis (Facebook, Google etc) as this used to be the endpoint that was used for public apis most often.
With OpenID Connect, the /authorize endpoint seems to be doing the authentication and authorization, so how should I be handling the consent page. My ONLY thought is to check if the client has grant type password and if it does, do not show the consent form and just proceed the request with authorized = true. Is this a correct approach? There is nothing written in the specification on that (or at least I didn't see anything about it).
As noted in https://www.rfc-editor.org/rfc/rfc6749#section-4.3 for the Resource Owner Password Credentials grant the user credentials are presented in a call to the token endpoint, not the authorization endpoint. The latter is only used for the Authorization Code grant.
Upon sending the authorization request back to the client, it is up to the discretion of the Authorization Server to present a consent screen for release of the information. According to the spec the Authorization Server should present it in a consumer scenario but one may choose to disable it in an enterprise scenario. That would be an implementation specific option to configure in the Authorization Server.

OpenID Connect Signin Page separate endpoint or authorize endpoint

How does OpenID Connect Authorization Code Flow work? Let's say a user made a request to app.example.com didn't have an access token or had an access token that is invalid. When the app redirected the user to authorization server: auth.example.com/authorize?response_type=code&client_id=CLIENT_ID&scope=openid&state=STATE&nonce=NONCE
Does the endpoint above have the signin screen? Or does signin happen in a separate endpoint (something like auth.example.com/signin)?
When the app redirects the user agent to the Authorization Server, the Authentication Server is supposed to authenticate the user. It can do that by presenting a login screen directly or by deferring to a separate authentication mechanism and/or server and/or screen. The authentication of the user is not prescribed by OAuth and is just something that is specific to the Authorization Server implementation. Both options are possible.

What is the format of the openID to Login with the CTP Sample Oauth Provider

Hi I'm just getting started on the v4 CTP so I can see me posting some basic questions as I get my head around it. I want to create a service provider so I'm looking at the WCF Oauth2
The first thing is when I go to login what is the format of the OpenID for use with the provided database? What is the process for this. I assume I'll get redirected to a screen where I put my password? And that interacts with the database?
Cheers, Chris.
The sample OAuth2 Authorization Server's database merely contains a couple of sample client entries so that the sample client can make requests. It has a users table that is automatically populated by each user who successfully logs in using their OpenID. So to your question regarding the "format of the OpenID" to use, any valid OpenID 1.1/2.0 identifier will work.
The OAuth2 authorization server sample doubles as an OpenID relying party in this respect, but its OpenID functions aren't the meat of the sample -- there are other sample OpenID RP sites that demonstrate more functionality in that respect. But being that OAuth2 auth server and OpenID RP are coupled in this way, the flow is that:
User visits OAuth2 Client site and indicates to the client that it may request access to user's data on the resource server.
Client redirects user to authorization server so the user may grant permission.
Authorization server prompts the user to log in, if not already logged in.
User enters OpenID
Authorization server redirects user to their OpenID Provider to log in using some credential (username/password, infocard, etc.)
OpenID Provider redirects user back to authorization server.
Authorization server sample then asks the user "do you want to share resource [x] with client [y]?" User confirms.
Authorization server records that user authorized client [y] to access [x] so that future requests from that client for that resource may be auto-approved without user intervention.
Authorization server redirects user back to Client with authorization grant.
Client receives the grant along with the user redirect and uses a direct HTTP request to the auth server to exchange that grant for an access token (and possibly a refresh token).
Client then includes the access token in HTTP requests to the resource server to access the user's private data.
I hope that helps.

Resources