In my web application, I want to provide the ability to pass authenticated users from my dashboard across to Grafana.
Once a user logged in my dashboard using credentials, a link to Grafana Dashboard will be displayed on my application. When user clicks that link, he/she will be redirected to Grafana page and automatically log in without displaying the Grafana login page. I don't want my users must encounter a second login screen, where they will be confused as to what username/password to enter.
I've followed Automatic login to grafana from web application, Auto login to grafana dashboard, Auto login to grafana from Web application using credentials or token
and Automatic login by token url, but no luck. I couldn't find appropriate & clean solution.
I'm using Grafana v6.2.5 installed on Ubuntu Server 18.04.
How can I implement it? Any help would be appreciated.
Server Details: Ubuntu Server 18.04, Apache 2.4.29
After some digging, I've found a workaround using Grafana's Generic OAuth Authentication.
Step 1: Create files with the following code in it.
GrafanaOAuth.php:
<?php
declare(strict_types=1);
class GrafanaOAuth
{
protected $user;
/**
* Create a new GrafanaOAuth instance.
* #param array $user
* #return void
*/
public function __construct(array $user)
{
$this->user = $user;
}
/**
* Redirect to authentication URL.
* #param string $state
* #return void
*/
public function auth(string $state): void
{
$state = urlencode($state);
$url = "http://localhost:3000/login/generic_oauth?state={$state}&code=cc536d98d27750394a87ab9d057016e636a8ac31";
header("Location: {$url}");
}
/**
* User access token.
* #return void
*/
public function token(): void
{
$token = [
'access_token' => $this->user['access_token'],
'token_type' => 'Bearer',
'expiry_in' => '1566172800', // 20.08.2019
'refresh_token' => $this->user['refresh_token']
];
echo json_encode($token);
}
/**
* User credentials.
* #return void
*/
public function user(): void
{
$user = [
'username' => $this->user['username'],
'email' => $this->user['email']
];
echo json_encode($user);
}
}
oauth/auth.php:
<?php
declare(strict_types=1);
require __DIR__ . '/../GrafanaOAuth.php';
/**
* Fetch the details of Grafana user from your database.
*/
$user = [
'username' => 'nbayramberdiyev',
'email' => 'nbayramberdiyev#outlook.com',
'dasboard_id' => 'oNNhAtdWz',
'access_token' => md5(uniqid('nbayramberdiyev', true)),
'refresh_token' => md5(uniqid('nbayramberdiyev', true))
];
(new GrafanaOAuth($user))->auth($_GET['state']);
oauth/token.php:
<?php
declare(strict_types=1);
header('Content-Type: application/json');
require __DIR__ . '/../GrafanaOAuth.php';
/**
* Fetch the details of Grafana user from your database.
*/
$user = [
'username' => 'nbayramberdiyev',
'email' => 'nbayramberdiyev#outlook.com',
'dasboard_id' => 'oNNhAtdWz',
'access_token' => md5(uniqid('nbayramberdiyev', true)),
'refresh_token' => md5(uniqid('nbayramberdiyev', true))
];
(new GrafanaOAuth($user))->token();
oauth/user.php:
<?php
declare(strict_types=1);
header('Content-Type: application/json');
require __DIR__ . '/../GrafanaOAuth.php';
/**
* Fetch the details of Grafana user from your database.
*/
$user = [
'username' => 'nbayramberdiyev',
'email' => 'nbayramberdiyev#outlook.com',
'dasboard_id' => 'oNNhAtdWz',
'access_token' => md5(uniqid('nbayramberdiyev', true)),
'refresh_token' => md5(uniqid('nbayramberdiyev', true))
];
(new GrafanaOAuth($user))->user();
custom.js:
$(function() {
'use strict';
if (location.pathname === '/login') {
location.href = $('a.btn-service--oauth').attr('href');
}
});
Step 2: Edit Grafana configuration file which is located at /etc/grafana/grafana.ini on Ubuntu / Debian, /usr/local/etc/grafana/grafana.ini on MAC, <GRAFANA_PROJECT_FOLDER>/conf/custom.ini on Windows.
Uncomment these lines and enter your client_id, client_secret, auth_url, token_url, api_url:
#################################### Generic OAuth ##########################
[auth.generic_oauth]
;enabled = true
;name = OAuth
;allow_sign_up = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url =
;token_url =
;api_url =
Like so:
#################################### Generic OAuth ##########################
[auth.generic_oauth]
enabled = true
name = OAuth
allow_sign_up = false
client_id = YOUR_APP_CLIENT_ID
client_secret = YOUR_APP_CLIENT_SECRET
scopes = user:email,read:org
auth_url = http://foo.bar/oauth/auth.php
token_url = http://foo.bar/oauth/token.php
api_url = http://foo.bar/oauth/user.php
Step 3: Place custom.js in /usr/share/grafana/public/build/index.html file (Ubuntu / Debian) at the bottom of <body> tag.
Step 4: Restart Grafana server.
sudo service grafana-server restart (Ubuntu / Debian)
brew services restart grafana (MAC)
For the example and detailed explanation, have a look at my Github repo.
Related
I need to call a private api in my app. the call works fine using php script.php.
However, when i copy the same php code into an action of a yii controller it gives me an error
failed to open stream: Connection timed
i tried removing the behaviors and other configurations to have a basic yii environment
anyone has an idea why this is happening?
here is some code
public function actionInfo() {
$url = "private url";
$data = array();
$data['function'] = "Getinfo";
$data['login'] = "login";
$data['password'] = "password";
$data['input'] = "data";
$post = http_build_query($data);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded",
'method' => "POST",
'content' => $post,
),
);
$context = stream_context_create($options);
$resultat = "";
if (!$resultat = file_get_contents($url, false, $context)) {
$resultat = "Echec de l'envoi de la requĂȘte";
}
$resultat = json_decode($resultat);
print_r($resultat);
echo "\r\n";
this code works fine outside yii but in this action it does not!!!!
it was a server configuration the firewall was blocking my id on the api side
I did the Laravel update from 5.2 to 5.3 and when I put it on the server came the surprise, the sessions were not working ...
I already tried to do some things, but all to no avail ....
Web routes file
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('auth/facebook', 'SocialAuthController#redirect');
Route::get('auth/facebook/callback', 'SocialAuthController#handleProviderCallback');
Authentication file
/**
* Obtain the user information from Facebook.
*
* #return Response
*/
public function handleProviderCallback()
{
$user = Socialite::driver('facebook')->user();
$authUser = $this->findOrCreateUser($user);
$id = $authUser['id'];
$email = $authUser['email'];
$password = $authUser['senha'];
$credentials = array('email' => $email, 'password' => $password, 'excluded' => 0);
Auth::attempt($credentials);
Auth::loginUsingId($id);
If i run dd( Auth::user() ); the auth is working, but after the redirect the session is lose
Kernel file
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
To fix this i change the file session.php
Look for
'cookie' => 'laravel_session'
And change to
'cookie' => 'app_session',
After it every works fine
The answer below is not working.
When I upgraded to version 5.3 I needed to move the routes file and found that I needed to remove the web middleware line and this problem started ...
I just readjusted the line and it's working now.
Route::group(['middleware' => ['web']], function () {
Route::get('auth/facebook', 'SocialAuthController#redirect');
Route::get('auth/facebook/callback', 'SocialAuthController#handleProviderCallback');
Below is my code for AuthController
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
//use App\Http\Requests\Request;
use Request;
use View;
use Hash;
use DB;
use Auth;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/home';
protected $redirectAfterLogout = '/login';
protected $username = 'user_name';
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
public function showLogin()
{
if (Auth::check())
{
return redirect('/home');
}
else
{
return View::make('index');
}
}
public function doLogin()
{
//echo 'test';
$input = Request::all();
$pass = Hash::make($input['password']);
//print_r($input);exit;
//echo $input['username'];exit;
/*DB::table('admin_user')->insert(
['user_name' => $input['username'], 'password' => $pass]
);*/
if (Auth::attempt(['user_name' => $input['username'], 'password' => $input['password']])) {
return redirect('/home');
//return View::make('home');
}
else
{
return redirect('/');
}
}
public function doLogout()
{
Auth::logout();
return redirect('/');
}
}
Below is my Route Code
Route::get('/',array('uses'=>'Auth\AuthController#showLogin') );
Route::post('/login',array('uses'=>'Auth\AuthController#doLogin'));
//Route::get('/login',array('uses'=>'Login#showLogin') );
Route::group(['middleware' => ['web', 'auth.basic']], function(){
Route::get('/home',['uses'=>'Home#getHome']);
Route::get('/logout',array('uses'=>'Auth\AuthController#doLogout') );
});
i am using user name instead of email id for Auth but below error is shown
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'email' in
'where clause' (SQL: select * from admin_user where email = admin
limit 1)
below is my kernal.php code
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
please help me how can i do login with username .
Thanks in advance.
Update:
Add the auth middleware to specific route
Route::group(['middleware' => ['web']], function(){
Route::get('/',array('uses'=>'Auth\AuthController#showLogin') );
Route::post('/login',array('uses'=>'Auth\AuthController#doLogin'));
Route::get('/home',['uses'=>'Home#getHome'])->middleware('auth');//update
Route::get('/logout',array('uses'=>'Auth\AuthController#doLogout') );
});
To redirect to intended page after login replace your doLogin() function with following:
public function doLogin()
{
$input = Request::all();
$pass = Hash::make($input['password']);
if (Auth::attempt(['user_name' => $input['username'], 'password' => $input['password']])) {
return redirect()->intended('/home');//This line is changed
}
else
{
return redirect('/');
}
}
Explaination:
intended() method redirects the user to the previous page, from where the user is redirected to login page. It expects a default route as a parameter, where user will be sent if he has came here directly.
Update 2:
add doLogout in your AuthController's constructor:
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'doLogout']);
}
You can simply override $username in AuthController by writing protected $username = 'username'.
When i try to request additional permissions from linkedin i do not get any permissions list in the dialog except for the basic permisiions. Could any1 point me to the solution. I tried urlencoding the permissions but still not getting any response. Here is my code: I am calling this function on click of 'Signup with Linkedin' button.
public function linkedinaccessAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$scope = 'r_basicprofile+r_emailaddress+r_network+r_contactinfo';
$options = array(
'version' => '1.0',
'siteUrl' => 'http://localhost/project/development/',
'callbackUrl' => 'http://localhost/project/development/signup/linkedinaccess',
'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken?scope=' . $scope,
'userAuthorizationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
'consumerKey' => 'myconsumerkey',
'consumerSecret' => 'myconsumersecret'
);
$consumer = new Zend_Oauth_Consumer( $options );
if (!isset($_SESSION ['LINKEDIN_ACCESS_TOKEN'])){
if(! empty ( $_GET )){
//consumer = new Zend_Oauth_Consumer( $options );
$accessToken = $consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['LINKEDIN_REQUEST_TOKEN'] ) );
echo $accessToken;
$_SESSION ['LINKEDIN_ACCESS_TOKEN'] = serialize ( $accessToken );
}else{
$requestToken = $consumer->getRequestToken();
$_SESSION ['LINKEDIN_REQUEST_TOKEN'] = serialize ( $requestToken );
$consumer->redirect();
}
}else{
$accessToken = unserialize ( $_SESSION ['LINKEDIN_ACCESS_TOKEN'] );
// Use HTTP Client with built-in OAuth request handling
$client = $accessToken->getHttpClient($options);
// Set LinkedIn URI
$client->setUri('https://api.linkedin.com/v1/people/~');
// Set Method (GET, POST or PUT)
$client->setMethod(Zend_Http_Client::GET);
// Get Request Response
$response = $client->request();
// Get the XML containing User's Profile
$content = $response->getBody();
print_r($content);
}
}
Thank you.
After rigorous searching finally got the solution from this Linkedin Post
Need to request linkedin permissions as a part of getRequestToken Call:
$requestToken = $consumer->getRequestToken(array('scope' =>'r_emailaddress'));
I had some really complicated code, and now I've made it ridiculously simple, and it doesn't work.
Currently it simply takes me back to the page with the login URL echoed out.
Code is here:
<?php
require 'facebook.php';
// Create our application instance
// (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => 'sd',
'secret' => 'sda',
));
// Get User ID
$user = $facebook->getUser();
if($user) {
echo $user;
} else {
$loginUrl = $facebook->getLoginUrl(array('redirect_uri'=>'http://www.facebook.com/pages/CharlesTestPage/225802194155435?sk=app_252946408094785','scope'=>'email'));
echo $loginUrl;
}
exit;
?>
Please. I have spent a whole paid work day on this now, and am at the point of crying, not only for myself but for my boss.
Cry.
Edit: OK, the weird thing is, if I have the redirect_uri set to the facebook tab, if it's not authenticated itself, then it constantly redirects in an infinite loop. However, if I remove the redire
This is what's working for me using PHP SDK 3.1.1. Try it and let us know if this works:
include('facebook.php');
session_start();
//facebook application
$config['appid' ] = "YOUR_APP_ID";
$config['secret'] = "YOUR_APP_SECRET";
$config['baseurl'] = "http://example.com/facebookappdirectory";
$config['appbaseurl'] = "http://apps.facebook.com/your-app-name";
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $config['appid'],
'secret' => $config['secret'],
'cookie' => true,
));
$user = $facebook->getUser();
$loginUrl = $facebook->getLoginUrl(
array(
'scope' => 'email'
)
);
if ($user) {
try {
//get user basic description
$userInfo = $facebook->api("/$user");
$fb_access_token = $facebook->getAccessToken();
} catch (FacebookApiException $e) {
//you should use error_log($e); instead of printing the info on browser
error_log('APP ERROR: '.$e);
$user = null;
}
}
if (!$user) {
echo "<script type='text/javascript'>top.location.href = '$loginUrl';</script>";
exit;
}
if (isset($_GET['code'])){
header("Location: " . $config['appbaseurl']);
exit;
}
Check for
if(isset($_GET['code'])){
$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
}
Facebook return userID only after the login and that code.