[ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Tim Johnson-2
Hi all,

I've uploaded a couple of Squeaky items to GitHub.

1)

First, a Morph designed to show the current status of the modifier  
keys, in the docking bar or otherwise:

https://github.com/tcj/ModifierKeysMorph

Included in that repo is both a FileTree repo and a simple .st fileout  
for doing a filein.  Pretty basic, should work for anybody (?).

It might be nice to add to SqueakMap — I've never done that and would  
be fine with being coached if anybody's up for it.

Aside: how nice is it to be able to create a complete menu bar item  
from scratch in just a few hours after work?  In fact, it took almost  
as long just to write this email.  Squeak for the win.

2)

Second, a rudimentary hack-and-slash I made last year of Zinc-SSO so  
it would use WebClient instead of Zinc:

https://github.com/tcj/WebClientOAuth2

It is designed for use with Seaside ... but maybe could be decoupled  
from Seaside too?

A lot of the code is just duplicated from Zinc-SSO, except that code  
which calls WebClient and/or WebUtils.  But it's also slightly less  
complex than Zinc-SSO because I only left in the bits that support  
Google's OAuth2.

I don't know if it could be useful to anyone in its current state, but  
I did use it in another project and it was working without issues.  I  
may have broken something when I extracted it for release here.

Cheers,
a Tim


Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

marcel.taeumel
Hi Tim,

thank you for sharing your efforts!

But it's also slightly less complex than Zinc-SSO because I only left in the bits that support Google's OAuth2.

I suppose that generic support for OAuth2 would be gold for Squeak Trunk. :-) Maybe with a simple way to add more service providers besides Google... GitLab, GitHub, Discord, Reddit, Bitbucket, ... 

Best,
Marcel

Am 11.06.2020 07:20:24 schrieb Tim Johnson <[hidden email]>:

Hi all,

I've uploaded a couple of Squeaky items to GitHub.

1)

First, a Morph designed to show the current status of the modifier
keys, in the docking bar or otherwise:

https://github.com/tcj/ModifierKeysMorph

Included in that repo is both a FileTree repo and a simple .st fileout
for doing a filein. Pretty basic, should work for anybody (?).

It might be nice to add to SqueakMap — I've never done that and would
be fine with being coached if anybody's up for it.

Aside: how nice is it to be able to create a complete menu bar item
from scratch in just a few hours after work? In fact, it took almost
as long just to write this email. Squeak for the win.

2)

Second, a rudimentary hack-and-slash I made last year of Zinc-SSO so
it would use WebClient instead of Zinc:

https://github.com/tcj/WebClientOAuth2

It is designed for use with Seaside ... but maybe could be decoupled
from Seaside too?

A lot of the code is just duplicated from Zinc-SSO, except that code
which calls WebClient and/or WebUtils. But it's also slightly less
complex than Zinc-SSO because I only left in the bits that support
Google's OAuth2.

I don't know if it could be useful to anyone in its current state, but
I did use it in another project and it was working without issues. I
may have broken something when I extracted it for release here.

Cheers,
a Tim




Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Tim Johnson-2

On Jun 10, 2020, at 11:21 PM, Marcel Taeumel wrote:

Hi Tim,

thank you for sharing your efforts!

But it's also slightly less complex than Zinc-SSO because I only left in the bits that support Google's OAuth2.

I suppose that generic support for OAuth2 would be gold for Squeak Trunk. :-) Maybe with a simple way to add more service providers besides Google... GitLab, GitHub, Discord, Reddit, Bitbucket, ... 

Thank you Marcel!

It has been a year since I was deep into this project, but I'll try to add some detail regarding its potential usefulness in Trunk:

As it is, this code implements the interactive, browser-based method of OAuth2.  This means it requires a browser to open up and for a human to physically log in.  It is likely possible for Squeak to launch the browser and then capture the token, as I have seen done in Python.  (The token would eventually expire, of course.)

It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":


I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I might just not be smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.

If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I think that would be very cool.

Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.

Best,
a Tim


* I think I made a class for this which I could contribute.




Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Levente Uzonyi
Hi Tim,

On Thu, 11 Jun 2020, Tim Johnson wrote:

>
> On Jun 10, 2020, at 11:21 PM, Marcel Taeumel wrote:
>
>       Hi Tim,
> thank you for sharing your efforts!
>
> > But it's also slightly less complex than Zinc-SSO because I only left in the bits that support Google's OAuth2.
>
> I suppose that generic support for OAuth2 would be gold for Squeak Trunk. :-) Maybe with a simple way to add more service providers besides Google... GitLab, GitHub, Discord, Reddit, Bitbucket, ... 
>
>
> Thank you Marcel!
>
> It has been a year since I was deep into this project, but I'll try to add some detail regarding its potential usefulness in Trunk:
>
> As it is, this code implements the interactive, browser-based method of OAuth2.  This means it requires a browser to open up and for a human to physically log in.  It is likely possible for Squeak to launch the browser and
> then capture the token, as I have seen done in Python.  (The token would eventually expire, of course.)
>
> It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":
>
> https://developers.google.com/identity/protocols/oauth2/service-account
>
> I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as
> RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I might just not be
> smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.
>
> If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I think that would be
> very cool.
>
> Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.
The Cryptography package seems to have this stuff implemented, though I
haven't verified the results. Here's how to use it:
Let's say privateKey is an RSAPrivateKey with your private key (See class
side methods and RSAPrivateKeyFileReader how to initialize it) and
message is your serialized json to sign. Then

  privateKey v15SignMessageHash: (HashFunction newSHA256 digestInfoAsn1DerEncodingFromMessage: message)

should return the signature.


Levente

>
> Best,
> a Tim
>
>
> * I think I made a class for this which I could contribute.
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Tim Johnson-2


On Jun 11, 2020, at 6:39 PM, Levente Uzonyi <[hidden email]> wrote:

It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":
https://developers.google.com/identity/protocols/oauth2/service-account
I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as
RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I might just not be
smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.
If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I think that would be
very cool.
Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.

The Cryptography package seems to have this stuff implemented, though I haven't verified the results. Here's how to use it:
Let's say privateKey is an RSAPrivateKey with your private key (See class side methods and RSAPrivateKeyFileReader how to initialize it) and message is your serialized json to sign. Then

privateKey v15SignMessageHash: (HashFunction newSHA256 digestInfoAsn1DerEncodingFromMessage: message)

should return the signature.

Thank you Levente.  When I mentioned algorithms I was hoping you might respond.  :) 

I found my old JWT code from last year on GitHub:  https://github.com/tcj/beaufort      (Oh no, it contains an old email address of mine in one of its tests...)

I loaded Cryptography into an image so I could run my tests again, and noticed that the Cryptography package has seen a lot of work this year.  Thanks for that.

So:  the tests I wrote last year (with a small change) pass now.  This could be very good news and may be worth further investigation.  Thank you again!  I will update my tests (& remove my old email address...?) and upload a new version of this package.

I am reminded that the issue I'd encountered last year was that HS256 could work, but RS256 could not.  Now, unit tests are passing for both.  (My BfJWTRFCTest>>#testConversion is not passing so I'll need to look into that.)

Here is the gist of my JWT signing code:

BfJWT>>#signedWith: aKey
| headerAndClaims |
self secret: aKey.
headerAndClaims := self headerAndClaims.
^ '{1}.{2}' format: { headerAndClaims . self signatureFrom: headerAndClaims }

... #signatureFrom: is implemented differently for HS256 versus RS256 subclasses of BfJWT.  My RS256 encoding was like this:

BfRS256 signatureFrom: aString
| signedMessage hashed privateKey |
privateKey := (Pkcs12PrivateKeyFileReader fromFile: 'timj-project-mar-2019-a94d67a8d0c8.p12') asPrivateKey.
signedMessage := privateKey signMessage: aString.
hashed := SHA256 new hashStream: signedMessage readStream.
^ hashed base64UrlEncoded

A year ago, I could have described how & why it wasn't working... but that information has left my brain now.

For what it's worth, Norbert Hartl's JSONWebToken also lacks support for this RS256 encoding format.


It seems to be a common issue around the internet that people find RS256 very difficult.

Thanks again,
Tim





Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Ben Coman


On Sun, 14 Jun 2020 at 01:40, Tim Johnson <[hidden email]> wrote:


On Jun 11, 2020, at 6:39 PM, Levente Uzonyi <[hidden email]> wrote:

It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":
https://developers.google.com/identity/protocols/oauth2/service-account
I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as
RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I might just not be
smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.
If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I think that would be
very cool.
Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.

The Cryptography package seems to have this stuff implemented, though I haven't verified the results. Here's how to use it:
Let's say privateKey is an RSAPrivateKey with your private key (See class side methods and RSAPrivateKeyFileReader how to initialize it) and message is your serialized json to sign. Then

privateKey v15SignMessageHash: (HashFunction newSHA256 digestInfoAsn1DerEncodingFromMessage: message)

should return the signature.

Thank you Levente.  When I mentioned algorithms I was hoping you might respond.  :) 

I found my old JWT code from last year on GitHub:  https://github.com/tcj/beaufort      (Oh no, it contains an old email address of mine in one of its tests...)

I loaded Cryptography into an image so I could run my tests again, and noticed that the Cryptography package has seen a lot of work this year.  Thanks for that.

So:  the tests I wrote last year (with a small change) pass now.  This could be very good news and may be worth further investigation.  Thank you again!  I will update my tests (& remove my old email address...?) and upload a new version of this package.

I am reminded that the issue I'd encountered last year was that HS256 could work, but RS256 could not.  Now, unit tests are passing for both.  (My BfJWTRFCTest>>#testConversion is not passing so I'll need to look into that.)

Here is the gist of my JWT signing code:

BfJWT>>#signedWith: aKey
| headerAndClaims |
self secret: aKey.
headerAndClaims := self headerAndClaims.
^ '{1}.{2}' format: { headerAndClaims . self signatureFrom: headerAndClaims }

... #signatureFrom: is implemented differently for HS256 versus RS256 subclasses of BfJWT.  My RS256 encoding was like this:

BfRS256 signatureFrom: aString
| signedMessage hashed privateKey |
privateKey := (Pkcs12PrivateKeyFileReader fromFile: 'timj-project-mar-2019-a94d67a8d0c8.p12') asPrivateKey.
signedMessage := privateKey signMessage: aString.
hashed := SHA256 new hashStream: signedMessage readStream.
^ hashed base64UrlEncoded

A year ago, I could have described how & why it wasn't working... but that information has left my brain now.

For what it's worth, Norbert Hartl's JSONWebToken also lacks support for this RS256 encoding format.


It seems to be a common issue around the internet that people find RS256 very difficult.

Just to round out options (but note, this was using Pharo)...

A couple of months ago I needed JWT RS256 for Google OAuth.  
Asking around I was advised that it was working in the following branch...

Although I didn't end up using that directly, but got JWT RS256 working as part of...
https://github.com/psvensson/cloudsdk-st/blob/master/CloudConversations-Core/CCGoogleConnectionTest.class.st  

cheers -ben


Reply | Threaded
Open this post in threaded view
|

Re: [ANN] ModifierKeysMorph & WebClientOAuth2 (Zinc-SSO port)

Levente Uzonyi
In reply to this post by Tim Johnson-2
Hi Tim,

On Sat, 13 Jun 2020, Tim Johnson wrote:

>
>
>       On Jun 11, 2020, at 6:39 PM, Levente Uzonyi <[hidden email]> wrote:
>
>       It is useful for SSO.  But for automated workflows, where human intervention is undesired, there is another type of OAuth2 which may be called "server to server" or apparently "two-legged OAuth":
>       https://developers.google.com/identity/protocols/oauth2/service-account
>       I tried and failed to implement this last year.  Where I failed was in computing the JSON Web Signature (JWS).  I could generate JWTs successfully*, but JWSs for Google require "SHA256withRSA (also known as
>       RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function)" which requires one very specific algorithm missing from SqueakSSL and which I simply could not engineer on my own at the time (or perhaps ever — I
>       might just not be
>       smart enough ;) ).  I was able to get as far as crafting the JSON in Squeak and then signing using Python's implementation of the algorithm and it would work.
>       If we could get server-to-server OAuth2 using WebClient, that would also allow us to, say, connect to Google Drive directly from Squeak, or be a client of Google Cloud Platform / Compute Engine, etc.  I
>       think that would be
>       very cool.
>       Sadly, I seem to recall this type of OAuth (and thus this algorithm) would also be necessary for GitHub/GitLab.
>
>
> The Cryptography package seems to have this stuff implemented, though I haven't verified the results. Here's how to use it:
> Let's say privateKey is an RSAPrivateKey with your private key (See class side methods and RSAPrivateKeyFileReader how to initialize it) and message is your serialized json to sign. Then
>
> privateKey v15SignMessageHash: (HashFunction newSHA256 digestInfoAsn1DerEncodingFromMessage: message)
>
> should return the signature.
>
>
> Thank you Levente.  When I mentioned algorithms I was hoping you might respond.  :) 
>
> I found my old JWT code from last year on GitHub:  https://github.com/tcj/beaufort      (Oh no, it contains an old email address of mine in one of its tests...)
>
> I loaded Cryptography into an image so I could run my tests again, and noticed that the Cryptography package has seen a lot of work this year.  Thanks for that.
>
> So:  the tests I wrote last year (with a small change) pass now.  This could be very good news and may be worth further investigation.  Thank you again!  I will update my tests (& remove my old email address...?) and upload a
> new version of this package.
>
> I am reminded that the issue I'd encountered last year was that HS256 could work, but RS256 could not.  Now, unit tests are passing for both.  (My BfJWTRFCTest>>#testConversion is not passing so I'll need to look into that.)
It fails because ByteArray >> #base64Encoded adds new line characters to
the resulting string. That should be changed in the Trunk.

>
> Here is the gist of my JWT signing code:
>
> BfJWT>>#signedWith: aKey
> | headerAndClaims |
> self secret: aKey.
> headerAndClaims := self headerAndClaims.
> ^ '{1}.{2}' format: { headerAndClaims . self signatureFrom: headerAndClaims }
>
> ... #signatureFrom: is implemented differently for HS256 versus RS256 subclasses of BfJWT.  My RS256 encoding was like this:
>
> BfRS256 signatureFrom: aString
> | signedMessage hashed privateKey |
> privateKey := (Pkcs12PrivateKeyFileReader fromFile: 'timj-project-mar-2019-a94d67a8d0c8.p12') asPrivateKey.
> signedMessage := privateKey signMessage: aString.
> hashed := SHA256 new hashStream: signedMessage readStream.
You're using #signMessage: which does SHA1withRSA, then apply SHA256 on
the result. The change I suggested will do SHA256withRSA.

> ^ hashed base64UrlEncoded
>
> A year ago, I could have described how & why it wasn't working... but that information has left my brain now.
>
> For what it's worth, Norbert Hartl's JSONWebToken also lacks support for this RS256 encoding format.
>
> https://github.com/noha/JSONWebToken/commit/4a4d20eaa6e84e2676a577f74bc6e24c1ead0047
>
> It seems to be a common issue around the internet that people find RS256 very difficult.

It's indeed more complex. RS256 requires RSA while HS256 is simply a HMAC
(AFAIK). But we have RSA implemented in Cryptography, and even though the
API could be more user-friendly and have more documentation, it can still
be done with a single line of code.


Levente

>
> Thanks again,
> Tim
>
>
>
>
>