Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth WP V1.2 #55

Merged
merged 25 commits into from
May 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea
.idea
.DS_Store
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,34 @@ Before you start, **make sure the admin user has a valid email that you own**, r
5. On the Settings of the Auth0 application change the Callback URL to be: http://your-domain/index.php?auth0=1. Using TLS/SSL is recommended for production.
6. Go back to **WordPress** Settings - Auth0 Settings edit the Domain, Client ID and Client Secret with the ones you copied from Auth0 Dashboard.

## Implicit Flow

There are cases where the server is behind a firewall and does not have access to internet (or at least, can't reach the Auth0 servers). In those cases, you can enable the Auth0 Implicit Flow in the advanced settings of the Auth0 Settings page.

When it is enabled, the token is returned in the login callback and then sent back to the WordPress sever so it doesn't need to call the Auth0 webervices.

## API authentication

The last version of the plugin provides the ability integrate with **wp-jwt-auth** plugin to authenticate api calls via a HTTP Authorization Header.

This plugin will detect if you have wp-jwt-auth installed and active and will offer to configure it. Accepting this, will set up the client id, secret and the custom user repository.

After the user logs in via Auth0 in your Api client (ie: using Lock in a mobile app) you will get a JWT (Json Web Token). Then you need to send this token in a HTTP header in the following way:

```
Authorization: Bearer ##jwt##
```

For example:

```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZW50IjoiVGhpcyBpcyB5b3VyIHVzZXIgSldUIHByb3ZpZGVkIGJ5IHRoZSBBdXRoMCBzZXJ2ZXIifQ.b47GoWoY_5n4jIyG0hPTLFEQtSegnVydcvl6gpWNeUE
```

This JWT should match with a registered user in your WP instalation.

You can use this feature with API's provided by plugins like **WP REST API (WP API)**.

## Technical Notes

**IMPORTANT**: By using this plugin you are delegating the site authentication to Auth0. That means that you won't be using the **WordPress** database to authenticate users anymore and the default WP login box won't show anymore. However, we can still associate your existing users by merging them by email. This section explains how.
Expand Down Expand Up @@ -50,7 +78,9 @@ Also, you can use the Auth0 widget as a shortcode in your posts.

The way to use it is just adding the following:

```
[auth0]
```

And can be customized by adding the following parameters:

Expand All @@ -67,8 +97,9 @@ And can be customized by adding the following parameters:

Example:

```
[auth0 show_as_modal="true" social_big_buttons="true" modal_trigger_name="Login button: This text is configurable!"]

```

All the details about the parameters on the lock wiki (https://github.com/auth0/lock/wiki/Auth0Lock-customization)

Expand All @@ -82,7 +113,9 @@ Under some situations, you may end up with a user with two accounts. **WordPres

You can style the login form by adding your css on the "Customize the Login Widget CSS" Auth0 setting and the widget settings

```
form a.a0-btn-small { background-color: red !important; }
```

The Login Widget is Open Source. For more information about it: https://github.com/auth0/lock

Expand All @@ -108,11 +141,13 @@ Internally, the plugin uses the dict setting to change the Auth0 widget title. W

To change the form_title in this case, you need to add the following attribute to the dict json:

```
{
signin:{
title: "The desired form title"
}
}
```

### How can I set up the settings that are not provided in the settings page?

Expand Down
165 changes: 134 additions & 31 deletions WP_Auth0.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Plugin Name: Wordpress Auth0 Integration
* Description: Implements the Auth0 Single Sign On solution into Wordpress
* Version: 1.1.8
* Version: 1.2
* Author: Auth0
* Author URI: https://auth0.com
*/
Expand Down Expand Up @@ -54,7 +54,6 @@ public static function init(){

add_filter('query_vars', array(__CLASS__, 'a0_register_query_vars'));


$plugin = plugin_basename(__FILE__);
add_filter("plugin_action_links_$plugin", array(__CLASS__, 'wp_add_plugin_settings_link'));

Expand All @@ -66,8 +65,49 @@ public static function init(){
WP_Auth0_Settings_Section::init();
WP_Auth0_Admin::init();
WP_Auth0_ErrorLog::init();
WP_Auth0_Configure_JWTAUTH::init();

add_action('plugins_loaded', array( __CLASS__, 'checkJWTAuth' ));
}

public static function isJWTAuthEnabled() {
if (!function_exists('is_plugin_active')) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active('wp-jwt-auth/JWT_AUTH.php');
}

public static function isJWTConfigured() {

return (
JWT_AUTH_Options::get('aud') == WP_Auth0_Options::get('client_id') &&
JWT_AUTH_Options::get('secret') == WP_Auth0_Options::get('client_secret') &&
JWT_AUTH_Options::get('secret_base64_encoded') &&
JWT_AUTH_Options::get('override_user_repo') == 'WP_Auth0_UsersRepo' &&
JWT_AUTH_Options::get('jwt_attribute') == 'sub'
);

}

public static function checkJWTAuth() {
if ( isset($_REQUEST['page']) && $_REQUEST['page'] == 'wpa0-jwt-auth' ) return;

if( self::isJWTAuthEnabled() && !self::isJWTConfigured() ) {
add_action( 'admin_notices', array(__CLASS__,'notify_jwt' ));
}

}

public static function notify_jwt() {
?>
<div class="update-nag">
JWT Auth installed. To configure it to work the Auth0 plugin, click <a href="admin.php?page=wpa0-jwt-auth">HERE</a>
</div>
<?php

}


public static function getPluginDirUrl()
{
return plugin_dir_url( __FILE__ );
Expand Down Expand Up @@ -130,7 +170,7 @@ public static function shortcode( $atts ){
ob_start();

require_once WPA0_PLUGIN_DIR . 'templates/login-form.php';
renderAuth0Form(false);
renderAuth0Form(false, self::buildSettings($atts));

$html = ob_get_clean();
return $html;
Expand All @@ -139,7 +179,7 @@ public static function shortcode( $atts ){
public static function login_auto() {
$auto_login = absint(WP_Auth0_Options::get( 'auto_login' ));

if ($auto_login && $_GET["action"] != "logout") {
if ($auto_login && $_GET["action"] != "logout" && !isset($_GET['wle'])) {

$stateObj = array("interim" => false, "uuid" =>uniqid());
if (isset($_GET['redirect_to'])) {
Expand Down Expand Up @@ -255,7 +295,15 @@ public static function render_form( $html ){
public static function init_auth0(){
global $wp_query;

if(!isset($wp_query->query_vars['auth0']) || $wp_query->query_vars['auth0'] != '1') {
if(!isset($wp_query->query_vars['auth0'])) {
return;
}

if ($wp_query->query_vars['auth0'] == 'implicit') {
self::implicitLogin();
}

if ($wp_query->query_vars['auth0'] != '1') {
return;
}

Expand All @@ -281,31 +329,18 @@ public static function init_auth0(){
$stateFromGet = json_decode(stripcslashes($state));

$domain = WP_Auth0_Options::get( 'domain' );
$endpoint = "https://" . $domain . "/";

$client_id = WP_Auth0_Options::get( 'client_id' );
$client_secret = WP_Auth0_Options::get( 'client_secret' );

if(empty($client_id)) wp_die(__('Error: Your Auth0 Client ID has not been entered in the Auth0 SSO plugin settings.', WPA0_LANG));
if(empty($client_secret)) wp_die(__('Error: Your Auth0 Client Secret has not been entered in the Auth0 SSO plugin settings.', WPA0_LANG));
if(empty($domain)) wp_die(__('Error: No Domain defined in Wordpress Administration!', WPA0_LANG));

$body = array(
'client_id' => $client_id,
'redirect_uri' => home_url(),
'client_secret' =>$client_secret,
'code' => $code,
'grant_type' => 'authorization_code'
);

$headers = array(
'content-type' => 'application/x-www-form-urlencoded'
);


$response = wp_remote_post( $endpoint . 'oauth/token', array(
'headers' => $headers,
'body' => $body
));
$response = WP_Auth0_Api_Client::get_token($domain, $client_id, $client_secret, 'authorization_code', array(
'redirect_uri' => home_url(),
'code' => $code,
));

if ($response instanceof WP_Error) {

Expand All @@ -322,7 +357,8 @@ public static function init_auth0(){

if(isset($data->access_token)){
// Get the user information
$response = wp_remote_get( $endpoint . 'userinfo/?access_token=' . $data->access_token );
$response = WP_Auth0_Api_Client::get_user_info($domain, $data->access_token);

if ($response instanceof WP_Error) {

self::insertAuth0Error('init_auth0_userinfo',$response);
Expand Down Expand Up @@ -420,15 +456,25 @@ private static function insertAuth0User($userinfo, $user_id) {
);
}

public static function insertAuth0Error($section, WP_Error $wp_error) {
public static function insertAuth0Error($section, $wp_error) {

if ($wp_error instanceof WP_Error) {
$code = $wp_error->get_error_code();
$message = $wp_error->get_error_message();
}
elseif($wp_error instanceof Exception) {
$code = $wp_error->getCode();
$message = $wp_error->getMessage();
}

global $wpdb;
$wpdb->insert(
$wpdb->auth0_error_logs,
array(
'section' => $section,
'date' => date('c'),
'code' => $wp_error->get_error_code(),
'message' => $wp_error->get_error_message()
'code' => $code,
'message' => $message
),
array(
'%s',
Expand Down Expand Up @@ -513,6 +559,8 @@ private static function login_user( $userinfo, $data ){
$joinUser = get_user_by( 'email', $userinfo->email );
}

// $auto_provisioning = WP_Auth0_Options::get('auto_provisioning');
// $allow_signup = WP_Auth0_Options::is_wp_registration_enabled() || $auto_provisioning;
$allow_signup = WP_Auth0_Options::is_wp_registration_enabled();

if (!is_null($joinUser) && $joinUser instanceof WP_User) {
Expand Down Expand Up @@ -560,6 +608,58 @@ private static function login_user( $userinfo, $data ){
wp_set_auth_cookie( $user_id );
return true;
}
}

public static function implicitLogin() {

require_once WPA0_PLUGIN_DIR . 'lib/php-jwt/Exceptions/BeforeValidException.php';
require_once WPA0_PLUGIN_DIR . 'lib/php-jwt/Exceptions/ExpiredException.php';
require_once WPA0_PLUGIN_DIR . 'lib/php-jwt/Exceptions/SignatureInvalidException.php';
require_once WPA0_PLUGIN_DIR . 'lib/php-jwt/Authentication/JWT.php';

$token = $_POST["token"];
$stateFromGet = json_decode($_POST["state"]);

$secret = WP_Auth0_Options::get('client_secret');
$secret = base64_decode(strtr($secret, '-_', '+/'));

try {
// Decode the user
$decodedToken = \JWT::decode($token, $secret, ['HS256']);

// validate that this JWT was made for us
if ($decodedToken->aud != WP_Auth0_Options::get('client_id')) {
throw new Exception("This token is not intended for us.");
}

$decodedToken->user_id = $decodedToken->sub;

if (self::login_user($decodedToken, $token)) {
if ($stateFromGet->interim) {
include WPA0_PLUGIN_DIR . 'templates/login-interim.php';
exit();

} else {

if (isset($stateFromGet->redirect_to)) {
$redirectURL = $stateFromGet->redirect_to;
} else {
$redirectURL = WP_Auth0_Options::get( 'default_login_redirection' );
}

wp_safe_redirect($redirectURL);
}
}

} catch(\UnexpectedValueException $e) {
self::insertAuth0Error('implicitLogin',$e);

error_log($e->getMessage());
$msg = __('Sorry. There was a problem logging you in.', WPA0_LANG);
$msg .= '<br/><br/>';
$msg .= '<a href="' . wp_login_url() . '">' . __('← Login', WPA0_LANG) . '</a>';
wp_die($msg);
}

}

Expand All @@ -574,12 +674,14 @@ public static function wp_init(){
}

// Initialize session
if(!session_id()) {
session_start();
}
// if(!session_id()) {
// session_start();
// }
}
public static function end_session() {
session_destroy ();
if(session_id()) {
session_destroy();
}
}

private static function setup_rewrites(){
Expand Down Expand Up @@ -701,4 +803,5 @@ function get_currentauth0userinfo() {
}
}
endif;

WP_Auth0::init();
4 changes: 4 additions & 0 deletions assets/css/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ textarea {
font-weight: bold;
text-align: center;
font-size: 18px;
}

.text-alone {
margin: 10px;
}
Loading