Closed kodok-jr closed 3 years ago
Hi.
You can check our own model to create yours: src/Models/KeycloakUser.php.
And the official documentation to understand how authentication works: Authentication.
About your error, check here if you are receiving the Keycloak Profile info.
Illuminate\Contracts\Container\BindingResolutionException
Unresolvable dependency resolving [Parameter #0 [
My auth.php
'guards' => [ 'web' => [ 'driver' => 'keycloak-web', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'keycloak-users', 'model' => App\User::class, ], ],
My User Model
class User extends KeycloakUser implements MustVerifyEmail { use Notifiable, SoftDeletes, RolevelModelTrait, SingleTableInheritanceTrait;
protected $table = 'users';
/**
* Single Tables Inheritance
* =========================
* extends to model Internal & External
*/
protected static $singleTableTypeField = 'type';
protected static $singleTableSubclasses = [Internal::class, External::class];
/**
* Get the email address that should be used for verification.
*
* @return string
*/
public function getEmailForVerification()
{
return $this->email;
}
/**
* Determine if the user has verified their email address.
*
* @return bool
*/
public function hasVerifiedEmail()
{
return ! is_null($this->email_verified_at);
}
/**
* Mark the given user's email as verified.
*
* @return bool
*/
public function markEmailAsVerified()
{
return $this->forceFill([
'email_verified_at' => $this->freshTimestamp(),
])->save();
}
/**
* Send the email verification notification.
*
* @return void
*/
public function sendEmailVerificationNotification()
{
$this->notify(new VerifyEmail);
}
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'username', 'email', 'password',
'name', 'nip', 'nik', 'no_kk',
'phone', 'address', 'gender', 'avatar',
'client_type', 'instance_id',
'is_verified', 'verification_token',
'type', 'state'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token'
];
/**
* Exception for enum type data only Internal table
*/
protected $enums = [
'client_type' => Internal::class.':nullable',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
// 'created_at' => 'datetime:j M Y H:i',
'created_at' => 'datetime:j M Y',
// 'created_at' => 'datetime:d/m/Y'
];
/**
* users statuses
*/
protected $states = [
'submitted',
'approved',
'rejected',
'banned',
'expired'
];
public function get_states()
{
return $this->states;
}
/**
* attributes parameter users button status
*/
public $stateButton = [
'Submitted' => [
[
'status' => 'approved',
'text-permission' => 'approve',
'text-button' => 'Approve',
'text-title' => 'Approval',
'color' => 'success'
],
[
'status' => 'rejected',
'text-permission' => 'reject',
'text-button' => 'Reject',
'text-title' => 'Rejection',
'color' => 'danger'
],
],
'Approved' => [
[
'status' => 'banned',
'text-permission' => 'banned',
'text-button' => 'Ban',
'text-title' => 'Banned',
'color' => 'danger'
],
],
'Rejected' => [],
'Banned' => [],
'Expired' => []
];
/**
* attributes color status (for css class)
*/
public $statusColor = [
'Submitted' => 'secondary',
'Approved' => 'success',
'Rejected' => 'danger',
'Banned' => 'danger',
'Expired' => 'warning'
];
/**
* User Observer
*/
protected static function boot()
{
parent::boot();
static::observe(UserObserver::class);
}
/**
* Role Relation
*/
public function roles () {
return $this->belongsToMany(config('rolevel.models.roles'), 'role_user', 'user_id', 'role_id');
}
public function role(){
return $this->roles()->first();
}
/**
* Instance Relation
*/
public function instance(){
return $this->belongsTo(Instance::class);
}
/**
* System Relation
*/
public function systems(){
return $this->hasMany(System::class, 'user_id');
}
/**
* Attributes string UCwords for view value
*/
public function getNameAttribute($value)
{
return ucwords($value);
}
public function getStateAttribute($value)
{
return ucwords($value);
}
/**
* Attributes string lowercase for record value
*/
public function setNameAttribute($value)
{
$this->attributes['name'] = strtolower($value);
}
public function setStateAttribute($value)
{
$this->attributes['state'] = strtolower($value);
}
/**
* Attributes Table Fields DataTable for Client Requests Integration System
* */
public function getClientRequestSystemTableFieldAttribute(){
return [ __('System Name'), __('Environment'), __('Public IP'), __('Time Frame'), __('Created At'), __('Status'), __('#') ];
}
/**
* Attributes DataTable Options for Client Requests Integration System
* */
public function getClientRequestSystemDataTableOptionAttribute(){
return [
'processing' => true,
'serverSide' => true,
'ajax' => route('admin.client.managements.integration.request.system.index'),
'columns' => [
['data' => 'name', 'class' => 'text-left'],
['data' => 'env', 'class' => 'text-left'],
['data' => 'public_ip', 'class' => 'text-left'],
['data' => 'effective_date', 'class' => 'text-left'],
['data' => 'created_at', 'class' => 'text-left'],
['data' => 'state', 'class' => 'text-center'],
['data' => 'action', 'class' => 'text-right', 'orderable'=>false]
],
'order' => [
[4, 'desc']
],
'filterColumn' => [
'exclude' => [6],
]
];
}
}
My AuthServiceProvider
class AuthServiceProvider extends ServiceProvider { /**
@var array */ protected $policies = [ // 'App\Model' => 'App\Policies\ModelPolicy', ];
/**
@return void */ public function boot() { $this->registerPolicies();
Auth::provider('keycloak-users', function ($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new KeycloakUser($app->make(User::class));
});
} }
KeycloakUser Model
class KeycloakUser implements Authenticatable { /**
@var array */
protected static $singleTableType = KeycloakUser::class;
/**
@var array */ protected $fillable = [ 'name', 'email' ];
/**
@var array */ protected $attributes = [];
/**
@param array $profile Keycloak user info */ public function __construct(array $profile) { foreach ($profile as $key => $value) { if (in_array($key, $this->fillable)) { $this->attributes[ $key ] = $value; } }
$this->id = $this->getKey();
}
/**
@return mixed */ // public function __get(string $name) // { // return $this->attributes[ $name ] ?? null; // }
/**
@return mixed */ public function getKey() { return $this->email; }
/**
@return string */ public function getAuthIdentifierName() { return 'email'; }
/**
@return mixed */ public function getAuthIdentifier() { return $this->email; }
/**
@return boolean */ public function hasRole($roles, $resource = '') { return Auth::hasRole($roles, $resource); }
/**
@codeCoverageIgnore */ public function getAuthPassword() { throw new \BadMethodCallException('Unexpected method [getAuthPassword] call'); }
/**
@codeCoverageIgnore */ public function getRememberToken() { throw new \BadMethodCallException('Unexpected method [getRememberToken] call'); }
/**
@codeCoverageIgnore */ public function setRememberToken($value) { throw new \BadMethodCallException('Unexpected method [setRememberToken] call'); }
/**
are you can help with this error, thanks ?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
can you explain step by step about this? "How to implement my Model?
We registered a new user provider that you configured on config/auth.php called "keycloak-users".
In this same configuration you setted the model. So you can register your own model extending Vizir\KeycloakWebGuard\Models\KeycloakUser class and changing this configuration.
You can implement your own User Provider: just remember to implement the retrieveByCredentials method receiving the Keycloak Profile information to retrieve a instance of model.
Eloquent/Database User Provider should work well as they will parse the Keycloak Profile and make a "where" to your database. So your user data must match with Keycloak Profile."
coz, i have error this [Keycloak Error] User cannot be authenticated