grails 3.0 facebook plugin spring social facebook using default appId 962223610477458 - facebook-graph-api

I'm using the
http://splix.github.io/grails-spring-security-facebook/index.html
java version "1.8.0_91"
Grails Version: 3.0.9 & Groovy Version: 2.4.5
I'm not sure where is is being inserted at. I've added the appid to application.yml, application.groovy, src\main\resources\application.properties.
````
DEBUG com.the6hours.grails.springsecurity.facebook.SpringSecurityFacebookGrailsPlugin - Facebook security config: [appId
:********, secret:********, apiKey:Invalid, domain:[classname:com.spontorg.FacebookUser, appUserConnectionPropertyName:u
ser], useAjax:true, autoCheck:true, jsconf:fbSecurity, permissions:[email, user_friends, public_profile], taglib:[langua
ge:en_US, button:[text:Login with Facebook], initfb:true], autoCreate:[enabled:true, roles:[ROLE_USER, ROLE_FACEBOOK]],
filter:[json:[processUrl:/j_spring_security_facebook_json, type:json, methods:[POST]], redirect:[redirectFromUrl:/j_spri
ng_security_facebook_redirect], processUrl:/j_spring_security_facebook_check, type:redirect, position:720, forceLoginPar
ameter:j_spring_facebook_force], beans:[:], host:localhost]
....
DEBUG com.the6hours.grails.springsecurity.facebook.FacebookAuthUtils - Redirect to http://127.0.0.1:8080/j_spring_securi
ty_facebook_check
`````
afterwards the URL redirect is
````
Location:https://www.facebook.com/dialog/oauth?client_id=962223610477458&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fj_spring_security_facebook_check&scope=email%2Cuser_friends%2Cpublic_profile&state=0-c68ca
````
then i get an error 72, and some message about the app is setup for public access, etc.

WELP...
It was me, i must have copy/pasted that in and never looked closely enough. IDK?
I checked the source code & it was pretty clearly pulling that value, rechecked and DOH!
finally got it, you need to match the host: with the value you put in ont the facebook app or it pukes again with a different error.
grails:
plugin:
springsecurity:
facebook:
appId: '###########'
secret: 'asfd!##$asfdasfd!#'
domain:
classname: 'com.domain.FacebookUser'
host: live.yourdomain.com
filter:
type: redirect
permissions: ['email','user_friends','public_profile']

Related

Keycloak Gitpod Flask OIDC: oauth2client.client.FlowExchangeError: Invalid response: 301

I'm trying to implement Flask-OIDC and Keycloak in a Flask app run inside a Gitpod workspace.
I'm running the application and the Keycloak server like this:
./keycloak-11.0.3/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 &
flask run --host=0.0.0.0 &
Based on this post
I'm able to redirect to the Keycloak login page for regular users from within the Flask application, but when I login with an existing user I get the following:
oauth2client.client.FlowExchangeError: Invalid response: 301
My client_secrets.json currently looks something like this:
{
"web": {
"auth_uri": "http://keycloak-hostname-gitpod/auth/realms/realm/protocol/openid-connect/auth",
"issuer": "http://keycloak-hostname-gitpod/auth/realms/realm",
"userinfo_uri": "http://keycloak-hostname-gitpod/auth/realms/realm/protocol/openid-connect/userinfo",
"client_id": "client",
"client_secret": "client_secret",
"redirect_uris": ["http://flask-app-hostname-gitpod/oidc_callback"],
"token_uri": "http://keycloak-hostname-gitpod/auth/realms/realm/protocol/openid-connect/token",
"token_introspection_uri": "http://keycloak-hostname-gitpod/auth/realms/realm/openid-connect/token/introspect"
}
}
Relevant client configuration inside keycloak:
Root URL: http://flask-app-hostname-gitpod/*
Valid Redirect URIs: http://flask-app-hostname-gitpod/*
Admin URL: http://flask-app-hostname-gitpod/*
Web Origins: http://flask-app-hostname-gitpod
I use http in all of these urls instead of https, because when I use https Keycloak says the redirect_uri is invalid. This seems to be the actual problem here since the gitpod urls use https, but I'm not sure how to handle this. I've tried some solutions like described here, but couldn't get them to work.
Relevant part routing:
#app.route("/")
def hello_world():
if oidc.user_loggedin:
return (
'Hello, %s, See private '
'Log out'
) % oidc.user_getfield("preferred_username")
else:
return 'Welcome anonymous, Log in'
#app.route("/private")
#oidc.require_login
def test():
return "test"
Parts of standalone.xml that might be relevant:
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" read-timeout="30000" proxy-address-forwarding="true" />
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true" read-timeout="30000" />
Update
After following changing the http urls to https as Jan Garaj suggested and setting the OVERWRITE_REDIRECT_URI I don't get the invalid response: 301 error anymore:
OVERWRITE_REDIRECT_URI = "https://flask-app-hostname-gitpod/oidc_callback"
Now I'm able to go to the keycloak login form, but on logging in I now get:
oauth2client.client.FlowExchangeError: Invalid response: 401.
These are the requests made:
https://keycloak-hostname-gitpod/auth/realms/realm/login-actions/authenticate?session_code=session_code&execution=execution&client_id=client&tab_id=tab_id
https://flask-app-hostname-gitpod/oidc_callback?state=state&session_state=session_state&code=code
Requests inside the network inspector:
After much trial end error I've finally figured out what the problem was.
The redirect problem in the original question was solved by setting OVERWRITE_REDIRECT_URI:
OVERWRITE_REDIRECT_URI = "https://flask-app-hostname-gitpod/oidc_callback"
The oidc_callback request was still not working however, I was getting this:
oauth2client.client.FlowExchangeError: Invalid response: 401.
Jan Garaj's comment made me realise the problem was that the token endpoint request was not working.
I had checked the token endpoint uri multiple times and copied the value from:
https://flask-app-hostname-gitpod/auth/realms/demo/.well-known/openid-configuration
but it still didn't work.
The reason it didn't work was actually unrelated to my Keycloak configuration, but the way my keycloak server was running inside Gitpod.
Gitpod set the port that the keycloak server was running on to private. Because the keycloak server was running on a private port, the request to the follwing url failed:
https://keycloak-hostname-gitpod/auth/realms/demo/protocol/openid-connect/token
After making the port public it worked.
if you already know that you want a particular port exposed, you can configure it in .gitpod.yml:
ports:
- port: 5000
onOpen: open-preview
- port: 8080
https://www.gitpod.io/docs/config-ports

JWT authentication between Django and Vue.js

I wish to create a public area on a website containing standard Django and templates. When a user logs in to the members area, they are logged in to a SPA (using Vue.js) and Django Rest Framework. I will be using JWT's to handle authentication between the SPA and backend once the user has logged in to the members area.
This is the user journey:
User browses around the public areas of the site (served by normal Django and templates).
User decides to signup / login to the members area.
Django Rest Framework generates a JWT for the user and returns the token along with the index.html of the SPA
The user continues to use the SPA with the JWT
Is the above possible and how would it be done? More specifically, the issue is that the user is not logging in to the SPA and requesting a JWT. They are logging in to regular Django and getting returned a JWT along with the SPA. That JWT would then be used from that point onwards.
This is something that I've used with laravel, but the principle should be the same.
I've placed vue-cli generated code into the subfolder frontend.
This is trimmed content of the file vue.config.js, which you need to add manually to the vue-cli project root.
const path = require('path')
/*
vue-cli is initialized in project subfolder `frontend`
and I run `npm run build` in that sub folder
*/
module.exports = {
outputDir: path.resolve(__dirname, '../public/'),
/*
https://cli.vuejs.org/config/#outputdir
!!! WARNING !!! target directory content will be removed before building
where js, css and the rest will be placed
*/
assetsDir: 'assets/',
/*
Where `public/index.html` should be written
- this is example for the laravel, but you can change as needed
- .blade.php is laravel template that's served trough laravel.
So you could inject JWT into `index.html`
- Check https://cli.vuejs.org/guide/html-and-static-assets.html
for the syntax before adding values
*/
indexPath: path.resolve(__dirname, '../resources/views/index.blade.php'),
devServer: {
host: '0.0.0.0',
port: 8021,
proxy: {
/*
Proxy calls from
localhost:8021/api (frontend)
localhost:8020/api (backend)
*/
'/api': {
target: 'http://localhost:8020',
changeOrigin: true,
}
}
}
};

Include cookie in swagger doc requests

My web service API will check whether a certain cookie is included in the requests, but I couldn't figure out how to include a cookie to my swagger doc api calls.
I've tried two approaches:
Adding cookie as a editable field like this in my .yaml file.
paths:
/myApi/create:
parameters:
- name: Cookie
in: header
description: cookie
required: true
type: string
In the html file of swagger ui, add
window.authorizations.add(
"Cookie",
new ApiKeyAuthorization("Cookie", 'Name=Val', 'header')
)
But in both of the approach my api doesn't get the cookie, I was wondering how I can do this? Thanks!
OpenAPI/Swagger spec 2.0 does not support cookie authentication. For the next version (3.0), the discussion to support it can be found in the following:
https://github.com/OAI/OpenAPI-Specification/issues/15
UPDATE: OpenAPI spec 3.0 will support cookie: https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#parameter-locations
Maybe it is too late, but you should check the following example:
swagger: '2.0'
info:
version: '1'
title: With Cookie Authentication
description: With Cookie Authentication
securityDefinitions:
myCookie:
type: apiKey
name: Cookie
in: header
paths:
/say-hi:
get:
summary: Say Hello
description: Say Hello
responses:
200:
description: OK
security:
- myCookie: []

Rails omniauth-saml + devise + ADFS issue

I am trying to integrate our ADFS login with our application which uses ActiveAdmin in combination with Devise. I succesfully added omniauth-saml for that purpose. The application now redirects to ADFS, the login succeeds but than fails on the callback. I get the error Invalid ticket.
When I try to look into the response on the server in the omniauth-saml lib I can see it says: #document=<UNDEFINED> ... </> and #decrypted_document=<UNDEFINED> ... </>
The initializers/devise.rb reads:
config.omniauth :saml,
assertion_consumer_service_url: 'https://my_server/admin/auth/saml/callback',
issuer: 'https://my_server/',
authn_context: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport',
idp_sso_target_url: 'https://my_adfs_server/adfs/ls/',
assertion_consumer_service_binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
assertion_consumer_logout_service_binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
idp_sso_target_url_runtime_params: {original_request_param: :mapped_idp_param},
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
idp_cert: idp_certificate,
request_attributes: {},
attribute_statements: {email: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'],
name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
first_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'],
last_name: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname']},
private_key: sp_key,
certificate: sp_certificate,
security: {authn_requests_signed: true,
logout_requests_signed: true,
logout_responses_signed: true,
metadata_signed: true,
digest_method: XMLSecurity::Document::SHA1,
signature_method: XMLSecurity::Document::RSA_SHA1,
embed_sign: false}
How can I solve this?
Addition:
It appears that REXML::Document is unable to decrypt the Cypher inside of the SAML response. It fails to do so without errorring. When I try to do it myself by using https://www.samltool.com/decrypt.php I see no problems with it though.
I picked the wrong certificate from ADFS metadata xml. Need to pick the signing, not the encryption certificate.
Found this by using https://www.samltool.com/validate_response.php for debugging.

Getting Facebook callback error even after enabling 'Embedded browser OAuth Login' and specifying the callback url

I have a rails(4.2.0) application that uses Facebook login functionality. The main gems are devise(3.4.0) and omniauth-facebook(2.0.0). I have registered the application on Facebook and have been using its test app for development. The Facebook login functionality works in the development env.
When trying to use the facebook login feature on the production server, I get error as "Given URL is not allowed by the Application configuration: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains."
The details for settings for test app being used in the dev env are as -
Settings:
Basic:
App Domains: 'localhost'
Website:
Site URL: 'http://localhost:3000'
Advanced:
OAuth Settings:
Embedded browser OAuth Login: Yes
Valid OAuth redirect URIs: "http://localhost:3000/users/auth/facebook/callback"
The details for settings for registered app being used in the production env are as -
Settings:
Basic:
App Domains: 'www.mysite.co'
Website:
Site URL: 'http://www.mysite.co'
Advanced:
OAuth Settings:
Embedded browser OAuth Login: Yes
Valid OAuth redirect URIs: "http://www.mysite.co/users/auth/facebook/callback"
I have specified the following in my secrets.yml
development:
secret_key_base: some_secret_key
facebook:
app_id: test_app_id
app_secret: test_app_secret
production:
secret_key_base: some_secret_key
facebook:
app_id: registered_app_id
app_secret: registered_app_secret
And have been using the creds from secrets.yml in the devise initialiser as
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
require 'omniauth-facebook'
config.omniauth :facebook, Rails.application.secrets.facebook['app_id'], Rails.application.secrets.facebook['app_secret'], scope: ['user_photos', 'email', 'public_profile']
The actual domain name(blackened) has no typos anywhere and is same wherever it is used.
Contains of routes.rb related to omniauth are as
cat config/routes.rb
Rails.application.routes.draw do
root 'home#index'
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
# routes related to other controllers
end
The routes are as below
bundle exec rake routes | grep user
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/facebook/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) users/omniauth_callbacks#:action
The only code related to omniauth in the entire app is as
$ cat app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, event: :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, kind: "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
Upon further digging the problem, it was observed that the error didnt occur when 'www.example.com' was specified in the url and hence, the callback worked. When 'example.com' was specified in the address bar and facebook login tried, the login crashed with the above error.
So, I fixed the above issue by making some changes to the settings in for the facebook app. I donno if this is the right approach but it worked out. Just making the change as in point 2 didnt solve the problem.
Changes are:
1) Specified the 'App Domains' with 'example.com' and 'www.example.com'
2) Enabled 'Client OAuth Login' to 'Yes'
3) Specified 'Valid OAuth redirect URIs' with 'http://example.com/users/auth/facebook/callback' and 'http://www.example.com/users/auth/facebook/callback'
Ok, so I assume that you have a web app NOT running on Facebook that simply uses the Facebook OAuth flow for login functionality, correct? If so, you must enable "Client OAuth Login" in your application settings for the production environment. If you don't, then the web OAuth flow will not work. See this article: https://developers.facebook.com/docs/facebook-login/security