背景说明
说到Identity Server 4,当我考虑客户端应用程序中的用户管理设计时,我遇到了障碍。
此时,我使用ASP身份用户帐户作为其用户存储设置了Identity Server。
我已经构建了用于将用户添加到Identity Server用户存储的UI。
我已经测试过设置一个MVC应用程序的客户端,我现在可以成功通过Identity Server进行身份验证并在我的客户端应用程序中接收openid身份令牌。
Identity Server正在为我的客户端应用程序提供身份验证。
现在,我需要专注于我的应用程序内的授权。这就是我遇到困难的地方,我需要在应用程序本地创建用户,其中存储了应用程序中的用户权限。
我需要将Identity Server中的用户链接/关联到客户端应用程序中的用户。
执行此操作的一种方法是将sub存储在身份令牌中,作为客户端应用程序数据库中的用户声明(Asp Identity)。这样,当用户进行身份验证时,我可以根据令牌中的sub在本地数据库中找到它们。
sub必须是身份服务器用户存储中用户的唯一ID。这样,如果更改了用户的电子邮件,我们仍然可以链接这两个用户帐户。
客户端应用程序中的用户帐户不需要密码或电子邮件地址,它将纯粹是用于整个应用程序授权的声明和角色,以及任何其他特定于应用程序的信息。
问题
在客户端应用程序中创建用户时,Identity Server和客户端应用程序之间的通信必须存在吗?
在这个过程中,这些任务应该完成吗?我正在寻找两个应用程序之间通信流程的一些指导?
编辑
客户端应用程序中根本没有用户帐户是否可行?
我的意思是用户的所有用户声明都存储在Identity Server的用户存储中。
当客户端使用IDP进行身份验证时,它仅请求特定于客户端应用程序的用户声明。
用户存储中的示例用户声明: -
当客户端应用程序A 进行身份验证时,它仅请求范围 clientA_role
这感觉很糟糕!
有什么建议吗?
答案 0 :(得分:1)
If you have many client applications then the way I recommend to do the user management is:
User Management Service:
Create a separate service for users management that identityserver will use as user store and applications will use as user repository when user metadata is needed.
Also why would you do something like:
Example user claims in the User Store :-
"clientA_role" : "administrator"
"clientB_role" : "user"
why not just "roles": "user"? and in your application you will protect your resources using Authorize[Role] annotation.
do not create different fields for different applications, think of it as general user management service, I am pretty sure that standardizing your identity management will make it easier and will gain you maintainability and flexibility.
IdentityServer service handles identity management:
might be a good idea to keep user store inside the same service providing authorization if you feel that your application does not have such deep users management needs.
again in this case, store standard claims and return the claims you need inside an id_token or access-token.
Update:
For a specific user that have different roles in different applications:
let us say we have the following:
1- User1 has user role in first app and admin role in second app, then
class plgPaypal extends JPlugin {
public $checkPossible = true;
protected $_params;
protected $_cfg;
public function __construct()
{
}
public function pay($price, $cfg, $params)
{
$return = new stdClass();
$return->state = 0;
$return->price = $price;
$this->_params = $params;
$this->_cfg = $cfg;
$auth = $this->_authorize();
$paypal_url = "api.sandbox.paypal.com";
$paypal_url = "api.sandbox.paypal.com";
$data = new stdClass();
$data->intent = "sale";
$data->payer = new stdClass();
$data->payer->payment_method = "paypal";
$data->transactions = array();
$data->transactions[0] = new stdClass();
$data->transactions[0]->amount = new stdClass();
$data->transactions[0]->amount->total = 34;
$data->transactions[0]->amount->currency = "USD";
$data->transactions[0]->payment_options = new stdClass();
$data->transactions[0]->payment_options->allowed_payment_method = "INSTANT_FUNDING_SOURCE";
$data->redirect_urls = new stdClass();
$data->redirect_urls->return_url = $this->_cfg->returnUrl;
$data->redirect_urls->cancel_url = $this->_cfg->cancelUrl;
$authorization = 'Authorization: Bearer ' . $auth->access_token;
$paypal_url = "api.sandbox.paypal.com";
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, "https://$paypal_url/v1/payments/payment");
curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($handle, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($handle, CURLOPT_TIMEOUT, 60);
curl_setopt($handle, CURLOPT_USERAGENT, "Payage"); // 1.09
$response = curl_exec($handle);
$response = json_decode($response);
if (!empty($response->links[1]->href)) {
$app = JFactory::getApplication();
$app->redirect($response->links[1]->href . '/execute');
return;
} else {
exit;
}
return $return;
}
public function cURLcheckBasicFunctions()
{
if (!function_exists("curl_init") &&
!function_exists("curl_setopt") &&
!function_exists("curl_exec") &&
!function_exists("curl_close")
) return false;
else return true;
}
private function _authorize()
{
$paypal_url = "api.sandbox.paypal.com";
$user = $this->_params->client;
$secret = $this->_params->secret;
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, "https://$paypal_url/v1/oauth2/token");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
curl_setopt($handle, CURLOPT_USERPWD, $user . ":" . $secret);
curl_setopt($handle, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Accept-Language: en_US'));
$response = curl_exec($handle);
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
$response = json_decode($response);
if ($code != 200) {
exit;
}
curl_close($handle);
return $response;
}
public function paymentCheck($link)
{
$auth = $this->_authorize();
$authorization = 'Authorization: Bearer ' . $auth->access_token;
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, 'https://api.sandbox.paypal.com/v1/payments/payment/' . $link);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
$response = curl_exec($handle);
$code = curl_getinfo($handle);
$response = json_decode($response);
curl_close($handle);
exit;
return $response;
}}
2- User2 has admin role in both apps, then:
User1.Roles{"FirstAppUser","SecondAppAdmin"}