What is the real purpose of Redirect_Uri in OpenIdConnect? - redirect

I am trying to setup OpenID Connect Authentication (Single-tenanted) for my web application. I understand how Reply Url in AAD is supposed to work. AAD admin registers a web application with SignInUrl, ReplyUri, AppIdUri,.. Microsoft AAD handles the complete user experience to prompt & validate the credentials. An attacker may not be able to pose legitimate site attack (since it is *.microsoftonline.com page).
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
Please suggest me how to view Redirect Uri. I would like to harness the real benefit.

What is the real purpose of Redirect_Uri in OpenIdConnect?
From the OpenID Connect, 3.1.2.1 Authentication Request:
redirect_uri
REQUIRED. Redirection URI to which the response will be sent.
This URI MUST exactly match one of the Redirection URI values
for the Client pre-registered at the OpenID Provider [...]
So, the purpose of redirect_uri is to tell the OpenID Provider (Azure AD, in your case) where the response to the request should be sent, after the user signs in.
Does it fight Redirect_Uri Attack?
The parameter itself offer the functionality described above, it doesn't mitigate any attack. It is the responsibility of the client (i.e. your app) and the OpenID Provider (i.e. Azure AD) to ensure they are doing the right thing to prevent exposing the risk of an attack (including an attack related to redirections).
For example, if an OpenID Provider did not validate that the redirect_uri from the request exactly matches a redirection URI configured for the client, then an attacker might be able to construct an authorization request with a redirect_uri pointing to a URL controlled by the attacker, and then trick a user into triggering the request. The response to the request would then be sent to the attacker, rather than to the relying party the user thinks they're signing in to.
There are other attacks related to redirect_uri which could happen if the relying party (i.e. your app, in this case) exposed a vulnerability (for example, by enabling an open redirection attack, or by authorizing a reply URL which is not actually in your control).
Many of these (and other) attacks, as well as the current best practices to mitigate or prevent them, are described in OAuth 2.0 Security Best Current Practice.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
This seems like there is an issue in your application. When Azure AD detects that the requested redirect_uri does not exactly match an authorized reply URI for the client, Azure AD does not redirect back to the client with an authorization code or any tokens.
It is possible that your app had already established a session previously, or is incorrectly processing the OpenID Connect flow. It's impossible to say without knowing the specific details of how the app is implemented.

Now I think I found the mystery behind the signin-redirect_uri anomalies.
Questions:
What is the real purpose of Redirect_Uri in OpenIdConnect? Does it fight Redirect_Uri Attack?
[OP] Yes, it does. If redirect_uri domain differs from AAD server Registration and web client, it invalidates the sign-in attempt.
I tried to send different Redirect_Uri from web client. Microsoft AAD fails by reply urls do not match error. But while refreshing the web application, it is signed in now. Should AAD not invalidate my attempt of logging in with illegitimate redirect uri?
[OP] Redirect_Uri does not behave when I hosted my application in localhost even on different ports or same domain. So, it ignores Redirect_Uri validation, if I click on Sign-In despite the first Reply-Uri-Mismatch error.
Please note that Redirect_Uri does handle Open redirect attack if an attacker wants to redirect the victim to illegitimate page for re-entering the credentials.

Related

SAML SSO: keeping users logged in after validating the SAML Assertion

I am implementing front-channel SAML 2.0 SSO golang Service Provider, with Okta as my Identity Provider (this is just a POC and should eventually work with any IdP).
Implementing the sign on process was straightforward with saml2 package. I've created the login endpoint that redirects to the SAML application login URL at the intended IdP, as well as the POST callback endpoint which is properly receiving the SAML assertion and is able to validate it. After that a session with a random cookie is created with the same TTL as the Identity Provider session TTL. So far everything works well (I haven't implemented Single Sign-Out yet, but I'm planning to).
However, when some time passes and the session expires, I'd like to renew it only if the user is still logged in with the Idp and hasn't been removed from the SAML Application. I would like to avoid redirecting the user to perform SSO again with IdP, because it would mean that if they are still logged in, they would be redirected back to the home page of my application. I wasn't able to find great sources on my options to go about it online.
Questions:
1.1 One solution that comes to mind is storing the requested URL in the RelayState parameter, whenever the session has expired, then redirect the user to the IdP SSO URL. When the redirect returns to the SAML callback POST endpoint, check the RelayState parameter and if set, redirect back to that (original) URL. That means that for users that use the system continuously, I would have to request Assertions very often. Does that make sense?
1.2 A second solution that comes to mind is to implement a back-channel of communicating directly from my SP to the IdP. That would allow me to verify a user is still logged in 'behind the users back'. If that's a sound idea:
a. Do I need to have dedicated code for each IdP?
b. Do I need to load an API key to the IdP which would allow secure communication?
c. Do I need to upload a public certificate to the IdP that would be able to verify that my SP signed the requests?
Will using the Assertion to get an OAuth 2.0 Access Token help me in achieving this?
I've chosen SAML 2.0 for now, since the environment is an enterprise oriented one and I thought it fits well with it based on what I read. Would using OpenID Connect instead help achieve my goals easier and fit well with enterprise oriented products?

Why google-oauth API requires redirect-url?

I'm trying to set up an authorization flow with google-oauth2 API.
The task is to authorize users with google accounts in my web-application which consists of frontend and backend parts.
The flow according to the documentation consists of 2 steps:
1) obtaining an auth code
2) exchanging an auth code for a token
In my flow, FE client obtains an auth code from google and submits it to BE, which then exchanges it for a token, so no redirect URL (or sometimes called callback URL) is used.
I do not understand why google API requires me to provide redirect_uri for the second step? Since this step is performed by a server, not a browser, I don't see any sense in this piece of info. The server just calls the POST /oauth2/v4/token google endpoint and receives token in response.
see step 4 at https://developers.google.com/identity/protocols/OpenIDConnect
According to this, it's to guard against stealing the access_token. If a service doesn't check the initial redirect_uri, the authorization code is sent to the hacker's redirect_uri, which can then exchange it for an access_token, i.e. illegal access to the user's account. To actually get the access_token, the redirect_uri is specified again and this time must be checked by the server against the ones that are registered for that application. At that point, the hacker is foiled as the fake redirect_uri doesn't match any of the legal ones. Apparently some servers don't check the redirect_uri during the authorization stage and sending the redirect_uri again when requesting the access_token is meant to provide a final safey check.

django rest framework - understanding authentication and logging in

I am a beginner to django rest framework (and to REST in general) and I have a server side which (for now) has a UserViewSet which allows to register new users and I can POST to the url from my android app just fine (I get 201 CREATED).
I read a lot about it, but I don't seem to fully the understand the concept of Login and Authentication in REST frameworks and specifically in django rest framework, and how it works.
Do you "Log in" (like in facebook for example) and then you can make requests?
What I understand\heard off:
you can Login to a API\website using your username and password (assuming off course that you have registered as a user and you are in the user database).
After you are Logged in - you will be able to make requests to views that allow access only to logged in\authenticated users.
Is that somewhat correct? I mean, is there a "Log in" url where you login and that's it? you are authenticated?
Also read somewhere that there isn't actually a login url, and you have to add your username and password to each request and then the request has to check if your details are in the User database?
To sum up, I am not really sure how does authentication/logging in (same thing?) happens in django REST framework... and would really appreciate a good explanation or an example..
Thanks a lot!
In a normal web application (removing the API from the question), a user would "log" in with their credentials (username/password, social tokens, etc.) and would receive a session cookie (assigned by Django) that allows them to authenticate in future requests on behalf of a user (realistically, themselves). This session cookie stays on their system for a limited period of time (two weeks by default) and allows them to freely use the website without authenticating again. If the session cookie needs to be removed, such that the person can no longer authenticate, the web application typically destroys the session cookie (or clears the session) which effectives "logs them out".
In the case of an API, it all depends on how the authentication works.
SessionAuthentication works just like as described above, as it uses Django's internal session system.
TokenAuthentication remembers the authentication information through a database-backed token (which is transmitted in the Authorization header) instead of a session cookie.
BasicAuthentication authenticates on every session (no persistent session) by passing the username and password on every request (base64 encoded through the Authorization header).
Other authentication methods generally work in the same way as TokenAuthentication.
So, here are some answers to specific questions which were raised
Do you "Log in" (like in facebook for example) and then you can make requests?
Using BasicAuthentication, you "log in" on every request by providing your credentials. With token-based authentication (TokenAuthentication, OAuth 2, JWT, etc.), you "log in" to receive the initial token and then your authorization is confirmed on every request.
Also read somewhere that there isn't actually a login url, and you have to add your username and password to each request and then the request has to check if your details are in the User database?
This is basic access authentication which you can use in DRF using the BasicAuthentication class.

Rest application and authorization

I would like to build my own REST app.
I'm planning to use oAuth as a main auth approach.
The question is: Can I use login and password as client_id and client_secret (in terms oAuth spec) ?
I don't have any third side applications, companies, sites etc... which will authenteficate my users.
I have my own REST server and JS-application.
Whole site will be made in usual(RPC) approach, but some private part will be done as RESTfull service, with enough stand-alone JS application.
UPDATED: I'm not sure that I even need full oAuth support. It seems to me that I can ask login and password on https page and then generate some token. Later i could use it to check is this user authenticated already or not. But in this case this oAuth become almost the same what we have in web aplications. I do not need oAuth to athorize users ?
I'm not consider HTTP(s) authotization because i don't want to send evrytime user and password to server.
No.
One if the main reasons OAuth exists is to allow integrations without users compromising their usernames and passwords.
If you plan on using username and password, look into xAuth as an option if you still want to sign your requests. More info: https://dev.twitter.com/docs/oauth/xauth.
But you could likely just as well go for HTTP Basic Authentication. At least if you publish your API over SSL. More info: http://en.wikipedia.org/w/index.php?title=Basic_access_authentication
I think you might get a better answer on the security site. See, for example, this question.
In any case, you need to start with a detailed assessment of what attacks you are trying to prevent and what attacks are "acceptable.". For example, if you are using HTTPS then you can probably accept the remaining danger of a man-in-the-middle attack, because it would require forging an SSL certificate. It is harder to say in general if a replay attack is acceptable.
One reasonable solution would be to create a time-limited temporary token by having the user authenticate over HTTPS with the username and password, generating a secure token with an expiration date, and then sending that token and expiration date back to the client. For example, you can create a (reasonably) secure token by taking the SHA1 hash of a secret plus the user name plus the expiration timestamp. Then the client can include the token, the user name, and the authentication timestamp in future requests and you can validate it using your secret and your clock. These need not be sent as 3 parameters; they can be concatenated into one string user|timestamp|token.
Register your application with SLI. SLI grants a unique client ID and a client secret that enables your application to authenticate to the SLI API. You must also register the redirect URI of your application for use in authentication and authorization flows.
Enable your application with specific education organizations so that the application can be approved for use in those districts.
Configure and implement the appropriate OAuth 2.0 authentication and authorization flow in your application, which includes managing sessions and authorization timeouts.

OAuth2 security considerations for client_id

When using User-agent flow with OAuth2 for mobile platform, there is no way for Authorization server to authenticate the client_id of the application.
So, anyone can impersonate my app by copying the client_id (and so get all access tokens on my behalf), and this is applicable to Facebook, Foursquare,...
This is not managed by OAuth2 ? Or I missed something ?
For Web applications (Web server flow), access token is stored on the server side, and the client is authenticated using secret key.
There's no good answer. Native app callbacks typically happen via custom registered URI schemes (e.g.: callback redirection URI is something like: myapp://oauth?code=xyz123). Unfortunately, any app can claim ownership of a given protocol scheme and receive the callback.
This problem is very synonymous with trying to lock down any protocol with "trusted clients". Think of the IM networks battle to lock out 3rd party clients (in early 2000's). Eventually they gave up - since whatever client & protocol endpoints are deployed could be reverse engineered by 3rd party developers.
Note: There is also some active discussion on this topic on the OAuth WG mailing list: http://www.ietf.org/mail-archive/web/oauth/current/msg08177.html
Normally client_id is associated with site's URL - OAuth responses/redirects will be sent only to the registrated Url. So attacker will not be able to receive results of the request on own site (unless somehow your and attacker pages are on the same domain).