Tin can launch auth parameter - tin-can-api

This document refers to an auth token parameter being passed to the launched activity
https://github.com/RusticiSoftware/launch/blob/master/lms_lrs.md
What is this parameter, and how is it used/passed back to the LRS with statements to authorise them? The API spec only refers to OAuth which uses different parameters, and http basic auth which is username/password.
https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#security

The "auth" query string value is intended for HTTP basic auth, it's to be passed after "Basic " in the HTTP Authorization header. That's not clear at all from the document you linked, that is how current adopters have implemented it. Since Basic Auth expects a base64 encoded username/password there, in practice this means the token sent by the LMS has to be a base64 encoded username/password, but the client shouldn't have to inspect it.
Some history: I originally created this document as a proposal for how an LRS could be integrated with an LRS, and expected some rounds of feedback and improvement during the development of the xAPI spec. That hasn't happened, but in the meantime there has been demand for a way to launch xAPI content and this mechanism has been widely adopted. CMI-5 is going to include a launch mechanism, and it's using this mechanism as a starting point: https://github.com/AICC/CMI-5_Spec_Current/blob/master/cmi5_runtime.md#80-content-launch-mechanisms. CMI-5 is still subject to change, so for now folks are sticking with this launch mechanism, but not particularly interested in refining it because of the expectation that it will be replaced.
That said, the omission you brought up is severe and it might be time to add some clarifications based on how the launch mechanism is being used in the wild.

Basic auth token follows standard basic auth formatting of username:password such as:
someusername:somepassword
Then base 64 encoded:
c29tZXVzZXJuYW1lOnNvbWVwYXNzd29yZA==
Prepend the word Basic and a space:
Basic c29tZXVzZXJuYW1lOnNvbWVwYXNzd29yZA==
Finally URL encoded:
auth=Basic%20c29tZXVzZXJuYW1lOnNvbWVwYXNzd29yZA%3D%3D
For example, with a SCORM cloud account you can get these from LRS section under Activity Providers. Where Key==Username and Secret==Password.

Related

Does custom security HTTP headers violate separation of concerns

Does custom application specific, security related HTTP headers violate separation of concerns, is it considered a bad practice? I realize using custom header to control the service would tightly couple the client with the service implementation. Or in this case, to control the security framework behavior. The context where I planned using the custom header is the following:
We are using token based authentication, where token has a fixed lifetime, and new token is issued each time authenticated client calls the web API. SPA client may call the server with AJAX in two contexts
User action (navigation and submit)
Automatic refresh (current view re-fetches data at fixed intervals)
Now, if user leaves the page open, the session never expires, as new token is generated for each automatic fetch. Somehow, we need to differentiate user action from automatic refresh in the server side, and issue new token only for user actions.
I realize Websocket based refresh would be one solution, but we have decided to stick with timed AJAX call due specific matters. Another solution would be to provide token refresh as a separate endpoint, but this would violate the DRY principle from client's perspective, and would be more cumbersome to setup with Spring Security.
Only remaining option is to embed the user/automated information in the request itself, and using a header seems a viable option here. A presence of certain header would prevent the token refresh. Easy to implement with a few lines of code.
I'm only concerned, if this couples the client too much with the service implementation. Technically, it doesn't couple client with the service, but the preceding security filter, thus leaking security concerns in the user interface. Ideally security stuff should be transparent to user interface, so new client could be coded without knowing anything about security (especially when cookies are used).
In the other hand, this solution isn't destructive or mutative. It's an optional feature. By client utilizing it, security is enhanced, but in either case never reduced (from the perspective of server, as it is). Now the question is, what principles using a optional header to enhance security is violating, and is it a valid solution in this context?
In my option the security should be maximized transparently, but I don't see how to not leak security concerns in the client in this situation.
It sounds like you're using your own home-built custom Token Authentication solution here. This is not a good idea.
I'll take a moment to explain WHY you don't want to do what you're proposing, and then what the better option is.
First off -- the problem that you're trying to solve here is that you don't want a user to remain logged into your site forever if they leave a tab open. The reason you need to fix this is because right now, you're assigning a new Access Token on EVERY REQUEST from the user.
The correct solution to handling the above problem is to have two types of token.
An Access Token that has a very short lifetime (let's say: 1 hour), and a Refresh Token that has a longer lifetime (let's say: 24 hours).
The way this should work is that:
When the user first authenticates to your service, the Access and Refresh tokens are generated with their respective timeouts.
These tokens are both set in HTTP cookies that the client-side JS cannot access.
From this point on, every time your user's browser makes a request to your service, you'll parse out the Access token from the cookie, check to see if it's valid, then allow the request.
If the Access token is no longer valid (if it has expired), you'll then parse out the Refresh token from the cookie, and see if that is valid.
If the Refresh token is valid, you'll generate a NEW Access token with another 1 hour lifetime, and override the old Access token cookie with the new on.
If the Refresh token is invalid, you'll simply return a 301 redirect to the login page of your app, forcing the user to manually re-authenticate again.
This flow has a number of benefits:
There is a maximum session length, which is technical (duration of Refresh token + duration of Access token) -- aka: 25 hours in this example.
Access tokens are short lived, which means that if a token is somehow compromised, attackers can't use it for very long to impersonate the user.
What's nice about the above flow is that it is a web authorization standard: OAuth2.
The OAuth2 Password Grant flow does EXACTLY what you're describing. It generates both types of tokens, handles 'refreshing' tokens, handles the entire thing from start to finish in a safe, standards-compliant way.
What I'd highly recommend you do is implement an OAuth2 library on both your server and client, which will take care of these needs for you.
Now -- regarding the tokens, most OAuth2 implementations now-a-days will generate tokens as JSON Web Tokens. These are cryptographically signed tokens that provide a number of security benefits.
Anyhow: I hope this was helpful! I author several popular authentication libraries in Python, Node, and Go -- so this comes from my direct experience working with these protocols over the last several years.

Do i need session store using JSON Web Token tokens ? Why not just using cookies?

I still cannot understand what is the main purpose of JWT. As for me the only purposes are:
to overcome CSRF
and to ensure better mobile support (because mobile apps in some cases don t support cookies).
Also there is a claim that with JWT you don't have to worry about session storage on the server side. This is not clear to me. How could JWT completely replace session storage on the server side? Does this mean that we put all session data into the JWT, encrypt it and send it to client on every response? But if so, does that mean the token that is issued by server will change depending on the data which we used to store in session? And as i understand the only thing that prevent us from using cookie this way(without session storage on the server side) is the size limit on cookie files - only 4kb.
Also do we still need to use SSL to prevent session hijacking?
Please tell me if my understanding is right or there is some other aspects.
I think there're too many legends about JWT. To understand its essence, we should get back to its original definition.
According to its official site:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a
compact and self-contained way for securely transmitting information
between parties as a JSON object. This information can be verified and
trusted because it is digitally signed.
So essentially, what JWT offers is just a way to transmit data. No more, no less. And because multi parties are involved, the format MUST be standardized. And once the format is standardized, libraries can be made to facilitate its adoption.
Again from the official site:
When should you use JSON Web Tokens?
There are some scenarios where JSON Web Tokens are useful:
Authentication:
This is the typical scenario for using JWT, once the user is logged in, each subsequent request will include the JWT,
allowing the user to access routes, services, and resources that are
permitted with that token. Single Sign On is a feature that widely
uses JWT nowadays, because of its small overhead and its ability to be
easily used among systems of different domains.
Information Exchange:
JSON Web Tokens are a good way of securely transmitting information between parties, because as they can be
signed, for example using public/private key pairs, you can be sure
that the senders are who they say they are. Additionally, as the
signature is calculated using the header and the payload, you can also
verify that the content hasn't changed.
So, Authentication is merely one of the possible use cases of JWT. Though it is indeed a typical usage of JWT.
As far as authentication is concerned, JWT can be used to replace session+cookie approach because it can save server's memory for storing sessions. But how big the benefit is depends on the user amount and your specific scenario. If there's only a few clients and no cross-domain authentication requirements, I don't think you need to give up the good old session+cookie approach.
Last but not the least, Session is not JUST meant for authentication. It is actually meant to place HTTP requests and responses within a larger context. I am not sure if JWT can replace session for that purpose given JWT's size limit. And IMHO, authentication just happened to be one of the use cases of session since such info must be user-specific. There are many other good scenarios to justify session, such as Shopping Cart.
JWTs in itself are just self-contained tokens and don't provide CSRF protection. The protocol used to deliver the JWT may (or should) provide means to prevent CSRF.
One area where JWTs are notably "better" than cookies is their cross-domain capability. You can read more on the comparison between tokens and cookies here: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
JWTs can be self-contained so they have all the information that you need in a verifiable container that would enable you to use them without storing them (or a reference to them). But there may be more data that you need in a session so avoiding session storage in general is not a reason in itself for moving to JWTs.
SSL is required for sure to prevent token leakage and session hijacking.

How to add multiple redirect URIs for Google OAuth 2?

I am trying to make Google OAuth 2 authentication work with a toy app I am running on my computer (at localhost:8080) using Social Auth for Java.
However when my app connects to Google to authenticate the user, Google responds with this error page:
My app, named "My Hobby App", is configured in the Developer Console as such:
In the Google OAuth 2 docs, it is specified that:
redirect_uri: One of the redirect_uri values listed for this project
in the Developers Console.
Determines where the response is sent. The
value of this parameter must exactly match one of the values listed
for this project in the Google Developers Console (including the http
or https scheme, case, and trailing '/').
I have a couple of questions:
How can I add multiple redirect_uris to my app?
Why is Google identifying my app as "Project Default Service Account" rather than "My Hobby App"?
It's actually easier than you think, unfortunately, it took me a couple of hours to figure it out.
How can I add multiple redirect_uris to my app?
Normally when you add multiple links to something on Google or elsewhere you separate it by , or ; but with Redirect URIs you have to use a new line, it's actually not very intuitive. So when you press the Edit Settings button, you can add to the URI and/or Origins if you have a couple more links, separated by newlines (enter).
No need for complicated app configurations or new keys.
Why is Google identifying my app as "Project Default Service Account" rather than "My Hobby App"?
On your second question: You have to go to the "Consent Screen" tab to change your app info such as your PRODUCT NAME, HOMEPAGE, LOGO, etc.
This answer may not be an exact answer to the question, but I think this might help those who are using Google OAuth for the first time and are wondering why their multiple URIs are not being recognized.
We use the redirect URI at 2 places in the code. First time, while fetching the auth code and a second time, when exchanging this code for an access token.
In the Google docs, it is clearly mentioned that the response for the auth code request(1st request) will be sent to the redirect URI. So, if you make the request from an endpoint A and specify the rediredt URI as endpoint B, Google will send the auth code to endpoint B. This is clear and worked fine without any errors.
Coming to the second request, the documentation is somewhat ambiguous. The redirect_URI parameter is described as below:
redirect_uri: The URI that you specify in the API Console, as described
in Set a redirect URI.
This is where I made a mistake in understanding how this works. Following a similar approach to the first call, I used a third endpoint C and passed this endpoint C in the redirect_URI parameter while making the second call. I got a URI mismatch error although my endpoints B and C are specified in the API console.
The problem is that, unlike in the case of first call, the response to the second call comes to the same endpoint from where the request is made. I made a request in python like below:
r = requests.post(token_endpoint, params)
r has the response with the token.
I was getting a URI mismatch because, I am supposed to use the same redirect_URI in both the calls.
So, for a single OAuth request, we need to use a single redirect_URI.
But then, that brings up the question, why are multiple redirect_URIs allowed in the API console for a single app. I am assuming that if we need to make multiple pairs of authCode-token calls in the same app, we have the leeway of using multiple redirect_URIs.

Designing a web api: How to authenticate?

I am designing a web api. I need to let the user authenticate themselves. I am a little hesistant to let the user pass in their username/password in cleartext.. something like: api.mysite.com/auth.php?user=x&pass=y
Another option i read about was Base64 encoding the username/password and then sending a HTTP request. So does that mean that on the server side;I would _GET['user'] and _GET['password'] and then somehow decode them?
Is that what twitter does: http://apiwiki.twitter.com/REST+API+Documentation#Authentication ?
Base64 is no protection at all. Use SSL for real security.
As mentioned by truppo, first use SSL.
What many web services do is have an "authenticate" service that returns a token that is then used later, and can be used in plaintext, since it's only valid for a limited amount of time. When it expires, the client simply does another authenticate.
The key benefit of this is that it reduces the number of SSL requests, which lightens the load on the server.
Just this week the IETF published a new draft discussing security properties of the various authentication mechanisms in HTTP. You should find helpful information there.
Personally I'd recommend at least to read about digest authentication and analyze if that's suitable for you.
Using SSL might also be an option. However, it also addresses additional issues at the expense of performance, cachability and others. It keeps the payload data confidential. If this is a requirement, then it's your way to go.
If this is a webservice, you'd better use more secure form of authentication. Look for example, at the LiveJournal protocol: Challenge-Response.
Please do not use regular usename/password authentication for the api. People really shouldn't be forced to put credentials from foreign services in a mashup service.
Please consider using oauth http://oauth.net/ or at least some challenge-response based system, like Eugene suggested.
One easy way would be to let the guest-service generate a token which is connected to his app and a user. If you put in some work you could even make the tokencreation secure to have only allowed foreign services with some private/public-key mechanisms.
The user has to authorize this token in your app before the guest service can use it to get authenticated.
I've found this article eye-opening.
In short: use a pair of API keys per user. One is for client authentication, one for parameters signing.

Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"

Disclaimer: I'm new to the REST school of thought, and I'm trying to wrap my mind around it.
So, I'm reading this page, Common REST Mistakes, and I've found I'm completely baffled by the section on sessions being irrelevant. This is what the page says:
There should be no need for a client
to "login" or "start a connection."
HTTP authentication is done
automatically on every message. Client
applications are consumers of
resources, not services. Therefore
there is nothing to log in to! Let's
say that you are booking a flight on a
REST web service. You don't create a
new "session" connection to the
service. Rather you ask the "itinerary
creator object" to create you a new
itinerary. You can start filling in
the blanks but then get some totally
different component elsewhere on the
web to fill in some other blanks.
There is no session so there is no
problem of migrating session state
between clients. There is also no
issue of "session affinity" in the
server (though there are still load
balancing issues to continue).
Okay, I get that HTTP authentication is done automatically on every message - but how? Is the username/password sent with every request? Doesn't that just increase attack surface area? I feel like I'm missing part of the puzzle.
Would it be bad to have a REST service, say, /session, that accepts a GET request, where you'd pass in a username/password as part of the request, and returns a session token if the authentication was successful, that could be then passed along with subsequent requests? Does that make sense from a REST point of view, or is that missing the point?
To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.
Okay, I get that HTTP authentication
is done automatically on every message
- but how?
Yes, the username and password is sent with every request. The common methods to do so are basic access authentication and digest access authentication. And yes, an eavesdropper can capture the user's credentials. One would thus encrypt all data sent and received using Transport Layer Security (TLS).
Would it be bad to have a REST
service, say, /session, that accepts a
GET request, where you'd pass in a
username/password as part of the
request, and returns a session token
if the authentication was successful,
that could be then passed along with
subsequent requests? Does that make
sense from a REST point of view, or is
that missing the point?
This would not be RESTful since it carries state but it is however quite common since it's a convenience for users; a user does not have to login each time.
What you describe in a "session token" is commonly referred to as a login cookie. For instance, if you try to login to your Yahoo! account there's a checkbox that says "keep me logged in for 2 weeks". This is essentially saying (in your words) "keep my session token alive for 2 weeks if I login successfully." Web browsers will send such login cookies (and possibly others) with each HTTP request you ask it to make for you.
It is not uncommon for a REST service to require authentication for every HTTP request. For example, Amazon S3 requires that every request have a signature that is derived from the user credentials, the exact request to perform, and the current time. This signature is easy to calculate on the client side, can be quickly verified by the server, and is of limited use to an attacker who intercepts it (since it is based on the current time).
Many people don't understand REST principales very clearly, using a session token doesn't mean always you're stateful, the reason to send username/password with each request is only for authentication and the same for sending a token (generated by login process) just to decide if the client has permission to request data or not, you only violate REST convetions when you use weither username/password or session tokens to decide what data to show !
instead you have to use them only for athentication (to show data or not to show data)
in your case i say YES this is RESTy, but try avoiding using native php sessions in your REST API and start generating your own hashed tokens that expire in determined periode of time!
No, it doesn't miss the point. Google's ClientLogin works in exactly this way with the notable exception that the client is instructed to go to the "/session" using a HTTP 401 response. But this doesn't create a session, it only creates a way for clients to (temporarily) authenticate themselves without passing the credentials in the clear, and for the server to control the validity of these temporary credentials as it sees fit.
Okay, I get that HTTP authentication
is done automatically on every message
- but how?
"Authorization:" HTTP header send by client. Either basic (plain text) or digest.
Would it be bad to have a REST
service, say, /session, that accepts a
GET request, where you'd pass in a
username/password as part of the
request, and returns a session token
if the authentication was successful,
that could be then passed along with
subsequent requests? Does that make
sense from a REST point of view, or is
that missing the point?
The whole idea of session is to make stateful applications using stateless protocol (HTTP) and dumb client (web browser), by maintaining the state on server's side. One of the REST principles is "Every resource is uniquely addressable using a universal syntax for use in hypermedia links". Session variables are something that cannot be accessed via URI. Truly RESTful application would maintain state on client's side, sending all the necessary variables over by HTTP, preferably in the URI.
Example: search with pagination. You'd have URL in form
http://server/search/urlencoded-search-terms/page_num
It's has a lot in common with bookmarkable URLs
I think your suggestion is OK, if you want to control the client session life time. I think that RESTful architecture encourages you to develop stateless applications. As #2pence wrote "each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP" .
However, not always that is the case, sometimes the application needs to tell when client logs-in or logs-out and to maintain resources such as locks or licenses based on this information. See my follow up question for an example of such case.

Resources