GenieFramework / GenieAuthentication.jl

Authentication plugin for Genie framework
MIT License
20 stars 11 forks source link

OAuth providers support #7

Open essenciary opened 2 years ago

essenciary commented 2 years ago

Google, FB, Apple, etc

jerlich commented 2 years ago

any progress on this?

essenciary commented 2 years ago

I'm afraid not - nor is this planned for the next few months tbh, due to lack of time. Will review PRs though, if anybody is interested to contribute these.

jiachengzhang1 commented 2 years ago

I can take a look at this

essenciary commented 2 years ago

@jiachengzhang1 that would be amazing! Happy to help with anything you need. For any questions, we can sync here or we can have a call as well to dive into the details.

jiachengzhang1 commented 2 years ago

@essenciary Finally have free time to work on this. I created a package for oauth2 (Google and GitHub at the moment). It's entirely decoupled from Genie, which users can use for any framework, and they need to create routes themselves; it'd be cleaner and more flexible this way IMO. Let me know your thoughts, it can always be integrated into the current GenieAuthentication plugin's structure as well.

An example of it,

using Genie
using Genie.Router
using Genie.Renderer
using Guard, Guard.Configuration

const options = Configuration.Options(;
    client_id="",
    client_secret="",
    redirect_uri="http://localhost:3000/oauth2/google/callback",
    success_redirect="/protected",
    failure_redirect="/no",
    scopes=["profile", "openid", "email"]
)

google_oauth2 = Guard.init(:google, options, Genie.Renderer.redirect)

route("/") do
    return "<a href="/oauth2/google">Authenticate with Google</a>"
end

route("/oauth2/google") do
    # this handles the Google oauth2 redirect in the background
    google_oauth2.redirect()
end

route("/oauth2/google/callback") do
    code = Genie.params(:code, nothing)
    # handle tokens and user details
    function verify(tokens::Guard.Google.Tokens, user::Guard.Google.User)
        println(tokens.access_token)
        println(tokens.refresh_token)
        println(user.email)
    end

    google_oauth2.token_exchange(code, verify)
end

Here's the repo, https://github.com/jiachengzhang1/Guard

AbhimanyuAryan commented 2 years ago

This is so good @jiachengzhang1 I think we can have multiple strategies for GenieAuthentication like passport js: https://www.passportjs.org/packages/ I see you have already done Github, Google

I will try it out and let you know :D

AbhimanyuAryan commented 2 years ago

also +1 for jwt

jiachengzhang1 commented 2 years ago

@AbhimanyuAryan exactly, that's what I had in mind. Ultimately, it'd be great if customized strategies can be added too.

essenciary commented 2 years ago

@jiachengzhang1 Fantastic, thank you! Yes, the approach is great. I can create a quick plugin wrapper for Genie apps to make the integration seamless by registering routes, setting up views, etc. I guess it makes most sense to have it integrated with GenieAuthentication.

AbhimanyuAryan commented 2 years ago

@jiachengzhang1 am I missing something?

pasted my client_id and client_secret along with

    redirect_uri="http://localhost:8000/oauth2/google/callback",
    success_redirect="/protected",
    failure_redirect="/no",
    scopes=["profile", "openid", "email"]

I get

ERROR: LoadError: UndefVarError: @google_str not defined
Stacktrace:
 [1] top-level scope
   @ :0
 [2] include(fname::String)
   @ Base.MainInclude ./client.jl:451
 [3] top-level scope
   @ REPL[1]:1
in expression starting at /Users/abhi/Git/geniedocbug/oauth.jl:18
in expression starting at /Users/abhi/Git/geniedocbug/oauth.jl:17
jiachengzhang1 commented 2 years ago

@AbhimanyuAryan @google_str is not part of the package, it seems that other part of the code is using it. Are you able to run the test.jl?

AbhimanyuAryan commented 2 years ago

I will check and will let you know

AbhimanyuAryan commented 1 year ago
(@v1.7) pkg> add Genie
    Updating registry at `~/.julia/registries/General.toml`
   Resolving package versions...
ERROR: Unsatisfiable requirements detected for package Genie [c43c736e]:
 Genie [c43c736e] log:
 ├─possible versions are: 0.9.4-4.18.1 or uninstalled
 ├─restricted to versions * by an explicit requirement, leaving only versions 0.9.4-4.18.1
 └─restricted by compatibility requirements with HTTP [cd3eb016] to versions: uninstalled — no versions left
   └─HTTP [cd3eb016] log:
     ├─possible versions are: 0.6.10-1.0.5 or uninstalled
     └─restricted to versions 1 by Umbrella [fb3c7edd], leaving only versions 1.0.0-1.0.5
       └─Umbrella [fb3c7edd] log:
         ├─possible versions are: 0.1.0 or uninstalled
         └─Umbrella [fb3c7edd] is fixed to version 0.1.0

@jiachengzhang1 what version of Genie are you using for extras?

jiachengzhang1 commented 1 year ago

@AbhimanyuAryan it seems to be an issue with HTTP, I'm using HTTP 1.0, but Genie compacts 0.8 and 0.9, let me test it with older versions

Update: HTTP 0.8 and 0.9 are included now, you can try again

AbhimanyuAryan commented 1 year ago

tests.jl worked for me. I need to check what's causing the above issue

hhaensel commented 1 year ago

This is cool progress.

May I also comment here? I'm not at all an experienced security guy, however, I feel that Umbrella needs some improvement.

As far as I see it Umbrella doesn't support any validity check yet.

The package OpenIDConnect.jl implements token validity check and state checking. Maybe it's worthwhile switching to OIDC. It might even remove the need for large Provider packages as all endpoints are retrieved from the .well-known/openid-configuration of the authentication provider.

I'm currently setting this up for an internal app, so I might contribute here in the near future, if desired.

I think we should really take to properly implement external authentication.