Microservices Security with Spring

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
one for being here we've got a for our workshop that I'm going to run through in about an hour my name is a deep sigh collie and part of the pivotal platform architecture team here in Toronto if you find this that it caused your ears to bleed I apologize I hope it's not too much blood on the floor security is a very vast topic if you want the slower for our version of this talk to me afterwards and we'll schedule we'll schedule something right so - I'm assuming everybody here knows what a micro service is because I'm not going to define it raise your hand if you know it on my crevasse is if you don't ask somebody who raised their hand but it is okay so our goal is to secure micro services and in order to do that we have to actually see what the problem is that we're trying to solve so our number one problem with micro service security is that micro services talk to each other so I might have a situation where my circle micro service calls the the triangle micro service which calls the Pentagon micro service and you know this is no different than what you do today you make calls over the network all the time in your enterprise systems and how have we solved this problem since the beginning like this we basically say stop identity papers please so on the communication links we need a way to know who's actually making the call and if we know who that person is we can actually make a security decision that makes sense to you guys so if I want to make security decision in the triangle micro service I need to know who's actually calling me and what permissions they have and stuff like that so that actually raises an interesting a bunch of interesting questions the first of which is okay let's actually talk about what is being spoken on those communication links so I'll open it up to you guys what's the protocol that micro sources are supposed to use HTTP REST raise your hand if that's what you think they should use all right a whole bunch of you good how about other protocols what other protocols might you find your meet yourself using rabbit yes AMQP whoo yeah bonus points how about Apache thrift anybody heard of that it's an RPC protocol that you know Facebook invented an open-source or maybe you're you're kind of a hipster and you like to use G RPC which is Google's http/2 based mobile friendly RPC protocol or maybe you have a custom legacy TCP protocol that you've invented that you have to support so the key idea here is when you're looking at micro services security do not make the mistake of assuming that it's only HTTP if you haven't guessed yet in this presentation I'm going to spend a lot of time talking about the protocols and the patterns for micro service security I do have a demo at the end that illustrates how all of this comes together with a spring and spring security so the key idea there's no best protocol so whatever security mechanism we pick we better make sure that it works with all the different protocols that we might use today or in the future so you can have a sure so our solution is that every every request to a micro service is going to include a security token of some kind which makes it easy to authenticate that an authorize that particular request which says ok now you have changed the problem so the problem of securing micro services becomes the problem of well what format should the security token be what is the type of ID that the micro service is looking for a passport a driver's license a birth certificate right does that make sense we're looking at how are the toque is supposed to be obtained like where do you get the token from what libraries are available in various programming languages for working with these tokens what information should be in the token which shouldn't be in the token so these are all some of the design choices you have to make so what format should you have for token you should use the answer is a standard token format she don't want to invent your own because inventing security token formats is quite hard so what are the choices you have well it depends on what's your favorite decade if you like the 90s you can pick Kerberos okay if you're using a windows login you are using Kerberos Active Directory is based on Kerberos if you like the 2000s you can use sam'l which is Excel I'll baste if you like the decade we're in right now you can use JWT or jot tokens so the interesting things about these token formats is that if you want to get yourself a sam'l token you need an actual sam'l server so the actual token format is related to the needs of the sam'l protocol if you want a Kerberos token ticket you need a Kerberos server you can't just get it from something else the interesting thing about jot tokens is if you want a jar token you can get it from anyone that's willing to give you one there isn't actually a protocol type to jot so when most of you out there type into Google micro service security you're going to see all sorts of bits around o authorial cans around various other protocols and it's a mishmash of stuff which is kind of like really confusing to get through so part of my goal today and I hope at the end you'll agree that this will be demystified so decision point number one what token form actually use for your micro services how many people here would guess that it should be Jah tokens raise your hand yes I will arrive at that but I'll take a few slides to argue why that is the correct choice so questions to ask is the token format standardized can the token be used by any protocol if I take the stokin and I try to stick it into a request parameter an HTTP URL will it work or will there be characters that violate the HTTP back what can I put it into an HTTP header can I squeeze it into a JMS in the header or a RabbitMQ header so these are all various things that you know is the token easy encodes to work with how many people here have tried working with sam'l raise your hand how many people would have preferred if you never started working with sam'l you know it can be it can be difficult to work with very complex standards so if you look at what's out there today this is a toolbox of standards and the interest of time I'm not going to read it I'm just going to say that there's a whole bunch of RFC s that are from the same kind of group of people that makes internet standards and when you look at all the standards it kind of looks something like this so at the bottom you have these JSON web algorithms JSON web key on top of that you have JSON web signatures web encryption on top of that you have JSON web tokens and then on top of that you have os/2 and open ID connect so what I want to do today is I want to show you how to use like how this what this layer looks like why this is a decent set of choices and how the whole picture comes together to to secure the micro-services so first one of these JSON web algorithms you're probably wondering what is this it is effectively a list of standard names for algorithms the reason why is if I'm going to exchange data with with Luke over here and I'm going to send him some encrypted data he needs to know which encryption algorithm I used so how do I tell them which one it is do I do I write it as a big long string that says I am using you know the RSA algorithm well if it's the RSA algorithm how big are the keys what are the settings that are used to configure it so this is about communicating security metadata so that's basically what it is so if you see for example the string HS 256 and that is from the jwa specification it means that you're using the hash of ten ocation code with the secure hashing algorithm that outputs a 256 bit hash how many people you know what Ayana is I am a hyena is like is looking the internet naming Authority you can go there and there's lists of stuff so there's an actual registry or all the standard algorithms what the strings should be and what the matching algorithms are so this is actually ridiculously useful if you have the following problem let's say you're going to encrypt some data and store it in your database who's done that and as part of that you actually want to know what remember in the database what algorithm you use to encrypt it now what would you set in that column you could put you know flags like algorithm a algorithm B algorithm C or you could use JWA so from now on every time you're trying to do remember what our encryption or cryptographic algorithm is being used check the jwa registry see if there's a string that represents what you want and use that then it's Android okay comments questions guys feel free to ask questions anytime so yep nope we don't want that so JSON web signatures it represents content which is secured with methods or sonication codes or JSON web encryption eventually I actually move put the slides a little bit out of order here but that's that's fine so what I want to basically say is this with digital signatures what you can tell is if something's been tampered with not stopping people from actually seeing what's that so if you look at your driver's license it has anti forgery features like it has the little Holograms it has other things it's not printed on a piece of paper it's not like you know the the picture has all sorts of patterns and at your photo to try and like fight for counterfeiting so that's what it does so it's a it's a great format for taking some data that you have and then encoding it as a JSON object why are we picking JSON because everybody knows how to work with JSON every programming language has a nice friendly library for handling that so here's what it looks like if you look at that JSON token our jws token you'll see that it has a header which tells you what is the algorithm is being used you can see out here HS 256 it has a payload the payload is an arbitrary JSON string the jws spec doesn't say what should be there you decide what you want to put in there right and then there is an actual signature which the format of this is going to end up matching whatever algorithm you're using that will depend on the algorithm what that would look like the signature so what this basically means is there's also what's called a compact serialization of jws which is you take the base64 encoding of the header you add a dot you take the base64 encoding of the payload you add a dot and then you do you take the signature and then you you put it all together into something that ends up looking like that and this is a string that you you can send around in URLs in HTTP headers anywhere you want so what's lovely about this format is it's just a string you can put a string in pretty much anything it's not just a string it's a string which has a URL safe encoding okay so that's why why it's kind of like the the JSON web signature its web friendly but it has uses elsewhere yeah yes yes it can definitely exceed the maximum header sizes that browsers and queries but if it depends on how big your payload is that's usually what it is that that's the determining factor could be a few kilobytes so these are some useful features of jws you can store in HTTP headers anyone can decode and view the payload so remember that if you have a JSON web signature it doesn't mean I can't see what's in your payload I can but I can't change it because if I do you'll detect that when you tala date the signature anyone can can verify stuff and it's easy to create these things and sign them with a digital certificate which means that if I'm a micro service and I get a jws I don't have to go back to a server to check if this is valid or not I can actually just use the public key of that server and see if this jws is actually secure right so if you are now going to send JSON documents if you're going to receive them if you're going to store an encrypted JSON document in your database say for example yes the credit card has been charged yes the money has been transferred whatever it is who thinks they would now use consider using jws as a data format for a field in the database perfectly valid I mean it's makes it kind of a bit future proof in the sense that you could decode it in the future easily so the metadata is all on them so there's another one JSON web encryption what do you guys think this will do anybody encrypt a payload that's exactly what it does so I'm not going to get into all the details again it has a header that tells you which algorithm is being used the key initialization vector the cipher text an authentication tag so naturally it's a lot bigger what I find is most libraries I run into right now seem to all implement the JSON web signature very few seem to be implementing the JSON web encryption I think it's just a matter of time before they do so same kind of comments apply if you're just working with JSON you want to encrypt a piece of JSON definitely take a look at JWT right but this is getting us now up the layer stack to the JSON web token which is the thing that we actually care about the most for micro-service security and as you can see from the diagram a JSON web token is either something that's signed or something that's encrypted either one would be considered a JSON web token right so the reason why we like it the reason why we use it is this URL safe and compact representation we can put it in headers we can put it in parameters and we have a choice as which algorithms to use so let's say you're deploying this your info info SEC team at your enterprise would be the one that decides which algorithms are allowed and disallowed they might have opinions as to what is a safe digital signature algorithm what's an unsafe one what are the minimum requirements so a great place to learn about dot is ja tokens is to go to this place called Jo it's got like a debugger you can copy and paste your your tokens in there and it will it will validate them but apparently my screen is not big enough my resolution must be 800 by 600 whoo okay let me let me see if I can fix that how much better okay so if I go to JWT that I oh you guys see it in total room and I can I can basically copy a token in here will decode it if you haven't played with it it's kind of fun to do a bit of that so what's interesting about the standard is it says okay what are some of the information you can put in the token you might want to put the ID of the token you might want to put when the token expires you might want to put that kind of information so instead of since the standard is unopp Enya nated about what you put in it it has some optional recommendations for example if you want to know who issued the token you would use ISS if you want to know when the token was issued you would call your field IAT issue that if you want to specify the user ID that the token belongs to you would use sub if you want to say when is the token expiring you would use exp but those are all optional you don't have to use them recommend that you do so you let your interoperable with others so here's how it ends up looking like inside of an HTTP request if you look at the bottom here what happens is that when you're making a call over HTTP to a your micro service you add an authorization header and then you just add a bearer token it's very very simple you're not like making any kind of special stuff comments questions about that alright alright so hopefully that's super easy I have another thing here like sometimes you may want to carry extra tokens because you might have you know information about the call that's propagating down a line of micro-services well you can have your own custom headers for your own frameworks where you could put your own other jock tokens in there that you could use for various pieces of information so let's say now you're like okay I'm not doing HTTP I'm now doing JMS or I'm doing RabbitMQ then take your jock token stick it into a JMS header or stick it into a rabbit and queue header or something along those lines you're going to have to at the receiving end look for that header the advantage of this type of approach is because it's piggybacking off the authorization header that's part of HTTP every web security framework understands HTTP authorization header so typically your web framework like spring security is going to look for that authorization header it's going to decode the token it's going to check the certificate of the token it's going to check the token is not expired it's going to do all that for you you don't have to do anything but I'm going to show you some code on that shortly yes so so it would use for example to check expiry you would first you could use the time that's in there and since the token is signed you can just check the clock correct yes now you are relying on that the advantage that you get is speed because you don't have to hop back to the issuer of the token and check if it's valid however you can do that you can actually take the token ID out of the token go back to the token server and say hey token server I just want to check is this token ID still valid and the token server would tell you you have a choice of how to use it JWT doesn't tell you which way to use it that's up to you so if i was building an application where speed was super important then I would use the digital certificate and the times to check and I'm going to assume that my computers all have NTP and the times are within you know reasonably synchronize the clocks otherwise I'm going to code my application if I'm really paranoid about security to always go back to the issuer and say here's the ID is this token valid yeah so they commented slash question that's being made is that this JWT token format is useful to send not just inside of a company but you could send it to external services you call you could offer it up I'd expect it from partners like being a jock token json-based it's easy to do that kind of thing now you're going to need to get into the higher-level protocols around open ID connect and others to go like what are the standard fields that I would put and I want to go there yet okay so we're going to speed up here a little bit so the key idea is is this every request our micro service is I have inside of it a security token that security token I received the request I look at the token I use the information in there to decide if I should allow the request to proceed or not all right and I'm going to use JWT for doing that very important JWT versus oauth2 keep in mind that OAuth 2 was created in 2012 and JWT was published officially in 2015 you can choose to use OAuth without using JWT you can choose to use JWT without using OAuth a lot of the time people kind of like assume that they go together they can but they don't have to just making out a comment so we figured out what format should our token be now let's take a look at like how are we going to get these tokens okay the answer is well you should get them from an OAuth 2 / open ID connect server of some kind all right that sounds good how do we do that so I'm going to skip here ahead and I'm just I'm going to skip over this one to say well if you're going to go get them from an OAuth 2 server there's actually 4 different ways you can do that the challenge with with these different ways is they're actually off - is designed for asking permission of the user so it's like hey deep do you want this application to be able to access your photos on Flickr hey deep do you want this application to be access your calendar on Gmail so it's about asking permission of the user that owns the data whether they want it or not now when I have microservices calling each other I don't want to pop up a dialog box hey micro-service number 27 way down the line would like permission if it can access these three database feels like that just wouldn't make any sense so so there's we're not going to use all the capabilities of Roth for that the two things that we're the thing that we're going to rely most for Microsoft security is client credentials okay so I'm going to talk just a little bit about about that in an OAuth there are you know a server a resource server an authorization server a whole bunch of client applications and some people that own the resources typically humans or or other apps and of these flows you know the simplest one to get your head around is the client create the password credentials I login I actually provide my username and password so I'll demonstrate this real quick you need to open up a terminal all right so here I am I'm going to do CF logger can you guys see my screen everybody wants big enough I'll just make another bigger so I'll do CF login I'm going to log into Cloud Foundry and you can see it's asking me for my password and I type in my password and I'm then going to be able to select unlock it and complete the login so now I can do things like you know use the application but the key thing is I type my username and password into the application now I don't have to keep logging in again well where does this application store my username and password it doesn't what it does is if I go into my dot CF folder there's a file here called well config dot JSON I can open that up and you can see in here there's something called an access token and I can take this whole access token and copy and paste it go over to Joe remove this all right iego and i can see like what algorithm is being used by Cloud Foundry to create the token I can see the information that's been put in there and you can see there's a lot more fields including a whole bunch of fields that only make sense to Cloud Foundry but that's an example of I get a token and then I don't need to now store my password I just stored the token and send it back over and over again okay comments questions so the so that's kind of a simple one where you just get the username and password there's a variant of this called client credentials where it's not the human users username and password it's the actual applications username and password so that's why I start startup let's say I'm the micro service that transforms money I go to the author to the OAuth server and I say hello our server please give me a token it says why should I even talk to you well here's my username and password my client ID and client secret as the money transfer micro service who's with me on that not representing a user I'm representing myself the actual piece of software so that's why it's kind of this is kind of a bit useful yeah well yes if you if you have that except that if you're talking about micro so the question was if I if every application has a client ID and client secret doesn't that mean that the person running that software has access to those the answer is yes but we're talking about micro services running in a data center so when I go to deploy my micro service I will provision brand-new client ID and client secret the other thing is the spec is kind of like says well you don't have to use a password it could be certificate based so I may authenticate myself to the to the OAuth server with a certificate ah yeah so the comment is if I'm running something like the Cloud Foundry CLI the client is seek ID at secret isn't a flow that you would use remember there are four flows with clutter with the OAuth and you have to pick the right flow for the use case so in that case if that client credentials would not be the right flow to pick you would use you know username and paddock client resource owner flow so that's part of the flexibility of auth cool question yeah so the yeah right yeah so I didn't yeah so what the comment is that a lot of the OAuth things tend to get explained using the authorization code flow which I'm intentionally staying away from explaining in the interest of time it is not very useful for things that don't have a UI if you do not have a user interface that can pop up a browser to kind of do the authorization it's not very useful okay sure yeah so sure so so here's what I don't want to do right now I'm interested in telling the big picture I'm happy to go offline and discuss specific details of that use case I do have an actual demo that does do authorization code flow and client credentials I want to get make sure to get to that okay so so to basically kind of complete it we're now at the oauth2 layer the next layer up in the standard stack is open ID connect and open ID connect builds on top of OAuth 2 JWT and TLS and it defines standardized identity token so it gets much more opinionated there's no more there's like the JWT spec says all fields are optional open ID Connect has like 15 fields that are required ok and you have no choice about the fields if you want to be open ID Connect you must follow those so as an example of that all these things that I showed you from jot that were optional now become required ok so the next thing we want to talk about is actually let's take a look at some micro service security patterns now that we have the basic foundation of the protocols that we are using let's take a look at what happens we have some sort of user interface but some of the data comes from the one micro service this other data comes from this one the blue one comes from the blue micro service what do we do is like let's say it's a web app is each one having a Jax calls directly to they you know the corresponding micro service that would be who would say that's a bad idea anybody else ok yeah it is a bad idea so what most of you do is you go like I know what to do I'm going to put a UI micro service and this thing is going to be you know my browser my native app will talk to it and then it will talk to the other micro services and kind of get data and other stuff then it turns out that your browser has more most like this is a desktop app it has more space so it requires more data your mobile apps needs a subset of that data or in a different order so you invent a whole entire K filtering parameters that you start sending to this thing to just get who has that like now a UI micro service where you filter out data and stuff thanks yeah most of you do it starts looking ugly recommendation read about this thing called back-end for front-end it's a pattern for building micro services which says actually split that up into different ones okay so the big picture behind this I'm trying to get to is you can end up with a client layer you can end up with what we would refer to as edge micro services think of the edge micro services is where requests enter the micro service ecosystem and from there they're going to flow to other stuff so as an example let's say it's a an online banking application my web client is going to talk to my micro service for the for that particular than the BFF which will turnaround call money transfer which might money transfer my turn around and call currency exchange and email template and various other micro services that are involved so now the question becomes this so what we've decided on is when micro services call each other we're going to include a job token and what we want the pattern to be is that a micro service gets a request that includes a Jah token the micro service checks that the joc token is valid it checks that the token has the correct Scopes in it and the information in the token is all that we need to make this happen to make security decision we're going to keep the model simple because we can't have the developer of the micro Service has a huge task to stick to right a secure one otherwise we'll be insecure that makes sense to you guys everybody agree keep it simple so this is super easy to implement with spring boot based spring based frameworks I want to actually switch to the demo and show you this okay so here I have a system that consists of the following micro services I know if you guys can read it I've got here a customer I've got a menu service and an order service so these are two micro services that don't have a UI and I've got an application called the customer portal where customers can go and make orders from the restaurant and and so that does have a UI so what happens here is if I try to visit localhost:8080 - oh I get redirected watch me do it again localhost:8080 - I'm getting bounced to my login server okay this is my open ID connect this happens to be the UA a which is part of Cloud Foundry now I'm going to log into this and I'm gonna click sign-in and it's going to take me to my application and in here I can go and I can look at the menu to see hey what orders do I want to place I can also go and look at my access token so this is the token that was given to this application by the OAuth server who's with me so far this token is sent to the menu micro service to view the menus it's also sent to the order micro service to place orders you guys with me okay now let's take a look now and see not from a point of view of the UI but from the point of view of the developer of the order micro service so let's go take a look at the code so in the order of micro service I would like to write a method to view which orders I've placed and you can see here the magic is this guy right here that's all I have to do I put at pre-authorized this is standard spring security annotation to say before you call this method please check that some conditions are met and the condition that being asked is to look inside of the oauth2 scope and check that the scope order docked me is listed in the token who's following me so far raise your hand okay so now if I switch to go here let's go back and take a look at this guy here you can see that the token that I have has a scope of open ID menu dot read order doc me if this scope did not exist that code would not execute silence questions yeah the scope is this concept of scope is basically a list an array of strings it's different the concept is defined an open ID Connect there is there are and it's it's just like whatever you want it to mean some scopes like open ID has a very specific meaning that's laid out by the Open ID spec others are yours to make you make your own scopes so in the for our version of this we go through how to design the scopes and what should be a scope what should an ESCO be a scope what's to fine-grained what's to coarse-grained there's a lot more to it but I just want to focus make sure everybody understands the mechanics so the second thing that I kind of want to show about this is is that when I look at the application itself you can see the second annotation at enable resource server just by adding this annotation to my application I now have said that this application will refuse to talk to anyone that does not present it with a valid jaw token I didn't have to do anything just say add enable resource server who's like this is simple I'm not a security specialist myself and I can do this so I'm excited about that now you're probably wondering well how does it actually validate that token right and the answer is again spring blue to the rest you by the way Chris I love that feature command + + lets has that now is that when i configure my spring security I just say spring security OS - resource you can see here that there's a JWT key URI and this is where the application can go to get the public key that's used to sign the token so if I go to my browser and I go to localhost 8080 - not 8080 you a a forward slash token underscore key oops wrong way go this is just a public endpoint on the server that issued the token I can go to that URL and I can retrieve the actual public key that's used for signing that Jah token who's with me so far so to kind of review the story and recap as a developer I of a spring boot application I go into my configuration file and I specify the URL where I can grab the certificate that's used to sign the tokens that I will receive step two is I go on my application and I say that I enable at resource server to say I'm an oauth2 resource server I want a jock token step three is when I write my code I use the add pre-authorized annotations to specify conditions and use the information in the token to make an authorization decision yeah question so I go to one micro-service defense customer data Kevin needs to be fully sent back to some other service but with it came some sort of signature that I need to give to the other micro server so that they make sure that I don't correct now where would you put that token if I had to like finish five or six different things right yeah so the question is what if I okay so it's a very good question which is I need to call other people and those people don't trust that I didn't tamper with their inputs so they're expecting my inputs that I sent to them to be signed and this is a use case of jaat where it's not you can use jot for it it's not an OAuth to use case it's you're now making your own token you use like there's Java libraries like JJ WT which make writing ja tokens super easy you go like builder dot make me one sign it you just make your own tokens so that's basically well you could use you could use H Mac with JWT because jawed gives you the choice remember that JSON web algorithms gives you a long list of algorithms that you could potentially use with your ja token and all of these have standard libraries so what I like the most about dot is if you go here to dot IO I forgot to do that so if we go down you can see all the dotnet libraries the python libraries the Java libraries the JavaScript Ruby pearl elixir I don't know what that is sounds like a drink go haskell okay you got you get the point you got a JA token you can pretty much work with it in any programming language so that's the reason why I would I would use that okay so I'm just going to go back here to my screen and try and wrap up with some some final thoughts about it so if I have like a money transfer service calling a currency exchange rate service the jot the currency exchange may not care who I am as a use it just knows it cares that money transfers authorised to call it that make sense to you guys so it's like making the distinction between you know services that actually need to know who the user is versus services that don't and arguably money transfer doesn't even need to know who I am need to know which application is invoking it is it the web application the native mobile application the the branch application and based on that it would kind of decide about things because a lot of security that this comes up in the 4-hour version of this is what should be in the token what should be in the payload there's a lot of things that you would instinctively want to put in the header that should absolutely not be there it is part of your business logic put it where it belongs in the payload so here's here's how it gets a little bit more interesting let's say my money transfer service wants to send out an email first it wants to do at the end of the transfer to say dear ID we've transferred a hundred dollars from your Canadian bank account to your US bank account and the exchange rate was blah blah blah and it wasn't done on this date so maybe I have a micro service that I can call I can say hey the email template micro service can you run template number 27 here's the JSON with the input to that template it gives me back nicely formatted HTML which I can then take and actually email now that particular application might have a single page GUI which marketing people use and legal people use to go in and edit these particular templates you know here's the French version the English version here's the you know the one with the blue fonts one with the green fonts and so when the email template service is being called by the single page app it absolutely cares who you are because it wants to know whether you have permissions or not like are you allowed to approve something or not but when it's being called from the money transfer side it doesn't care it just says do you have the permission to execute a template so this is where when you start looking at these particular things the design of the scope oops and what you put in the token becomes very important and I'm out of time so I apologize for you know I did my best to do the for our workshop and 15 minutes so I'm happy to take questions for the rest of the day offline okay so these are all the things I skipped over so thanks very much you
Info
Channel: SpringDeveloper
Views: 23,914
Rating: 4.9118457 out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud, security, OAUTH, microservice
Id: cKjgkNt-tFg
Channel Id: undefined
Length: 44min 54sec (2694 seconds)
Published: Thu Nov 03 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.