پشتیبانی از OAuth 2.0

بررسی کلی

ThingsBoard به شما امکان می‌دهد تا قابلیت Single Sign-On را برای مشتریان خود فراهم کنید و با استفاده از پلتفرم‌های مدیریت کاربران خارجی که پروتکل OAuth 2.0 را پشتیبانی می‌کنند، خودکار تنانت‌ها، مشتریان یا مشتریان فرعی را ایجاد کنید.
فهرستی از پلتفرم‌هایی که پروتکل OAuth 2.0 را پشتیبانی می‌کنند: Google، Okta، Auth0 و غیره.

جریان احراز هویت OAuth 2.0

ThingsBoard نوع Authorization Code را برای تبادل یک کد احراز هویت برای یک توکن دسترسی پشتیبانی می‌کند.
بازگشت کاربر به مشتری ThingsBoard از طریق آدرس URL بازگردانده شده، پلتفرم کد احراز هویت را از URL دریافت می‌کند و از آن برای درخواست توکن دسترسی از پلتفرم مدیریت کاربران خارجی استفاده می‌کند. با استفاده از Mapper اصلی یا Mapper سفارشی، شیء اطلاعات کاربر خارجی به کاربر OAuth 2.0 داخلی ThingsBoard تبدیل می‌شود. پس از این مرحله، جریان عادی احراز هویت ThingsBoard انجام می‌شود.

شرح سناریو

در این نمونه، ما قصد داریم از Google برای احراز هویت استفاده کنیم. کاربر وارد حساب کاربری Tenant خواهد شد و نام Tenant برابر با ایمیل کاربر خواهد بود. اگر Tenant در سیستم وجود نداشت، Tenant جدید ایجاد خواهد شد.

در مرحله دوم، قصد داریم یک ارائه‌دهنده خارجی جدید برای احراز هویت، یعنی Auth0 اضافه کنیم. در این حالت، کاربر وارد حساب کاربری Tenant خواهد شد که نام آن برابر با دامنه ایمیل کاربر خواهد بود. علاوه بر این، برای هر کاربر، یک مشتری جدید ایجاد خواهیم کرد و نام مشتری برابر با ایمیل کاربر خواهد بود.

برای نقشه‌برداری اطلاعات کاربر خارجی از پلتفرم‌های Google و Auth0، از یک نقشه‌برداری پایه داخلی استفاده خواهیم کرد.

اگر عملکرد نقشه‌برداری پایه نیازهای تجاری شما را برآورده نکند، می‌توانید نقشه‌برداری سفارشی را پیکربندی کنید تا بتوانید پیاده‌سازی ایجاد کنید که به نیازهای خاص شما متناسب باشد.

ورود با Google

برای استفاده از پلتفرم احراز هویت Google OAuth 2.0 برای ورود، باید یک پروژه در Google API Console راه‌اندازی کرده و از اطلاعات احراز هویت OAuth 2.0 دریافت کنید.

لطفاً طبق دستورالعمل‌های صفحه OpenID Connect، OAuth 2.0 Client را پیکربندی کنید. پس از تکمیل دستورالعمل‌های فوق، باید یک OAuth Client جدید با اطلاعات احراز هویت متشکل از شناسه مشتری (Client ID) و رمز مشتری (Client Secret) داشته باشید.

لطفاً آدرس بازگردانی پیش فرض ThingsBoard را که در این مثال قرار است استفاده کنیم، به بخش آدرس بازگردانی مجاز اضافه کنید.

http://localhost:8080/login/oauth2/code/

پیکربندی ThingsBoard

1. به عنوان یک مدیر سیستم (sysadmin@thingsboard.org / sysadmin) به ThingsBoard خود رفته و وارد شوید.
2. تنظیمات عمومی را بررسی کنید و به بخش “آدرس پایه” بروید. در اینجا مطمئن شوید که آخر “آدرس پایه” شامل “/” نباشد. به عنوان مثال، از “https://127.0.0.1:8080/” به جای آن از “http://127.0.0.1:8080” استفاده کنید.
3. سپس در بخش “صفحه اصلی”، آیکون “OAuth2” را پیدا کرده و روی آن کلیک کنید.

تنظیمات OAuth2 را فعال کنید و روی “+ اضافه کردن” کلیک کنید. سپس در پنجره‌ای که ظاهر می‌شود، روی “localhost” کلیک کنید تا به تنظیمات بیشتر بروید.

پروتکل مورد نیاز را انتخاب کنید. اگر تصمیم می‌گیرید از پروتکل HTTP استفاده کنید، حتماً پورت 8080 را در نام دامنه (localhost:8080) ذکر کنید. در این مثال، ما تنظیمات ارائه دهنده Google را پیکربندی خواهیم کرد. روی این بلوک کلیک کنید.

لطفاً اطلاعات مربوط به مشخصه مشتری (Client ID) و رمز مشتری (Client Secret) را از کنسول Google API خود ارائه دهید. سپس منوی تنظیمات سفارشی را گسترش دهید.

بیایید تنظیمات بلوک عمومی را انجام دهیم. از این لینک استفاده کنید تا لیستی از آدرس‌های URL به روزرسانی شده مانند accessTokenUri، authorizationUri و غیره را مشاهده کنید. در فیلد روش احراز هویت مشتری، POST را انتخاب کنید. سپس گزینه “Allow user creation” را تیک بزنید. به فیلد scope عبارت‌های openid، email و profile را اضافه کنید. سپس به بلوک Mapper بروید.

نوع Basic را انتخاب کرده و در صورت لزوم، فیلدها را پر کنید (که در این مقاله در بخش Basic mapper به طور مفصل توضیح داده شده است). برخی از تنظیمات فقط در نسخه حرفه‌ای (Professional Edition) موجود است. سپس تنظیمات را ذخیره کنید.

به طوری که پیکربندی های oauth2 به دست آمده برای Google شبیه به موارد زیر خواهد بود.

اگر به صفحه ورود به سیستم برویم، یک گزینه ورود اضافی با نام Google خواهیم داشت.

با کلیک بر روی آن و انتخاب یکی از حساب‌های Google خود، وارد ThingsBoard خواهیم شد و با آدرس ایمیل Google خود به عنوان ایمیل مدیر مستأجر وارد سیستم خواهیم شد.

اگر به‌عنوان مدیر سیستم وارد شوید، می‌بینید که نام مستأجر ایمیل Google ما است، طبق نقشه‌برداری اولیه:

ورود با Auth0

حالا بیایید یک تامین کننده دیگر را به لیست خود اضافه کنیم – Auth0. این بار ما قصد داریم مشتریانی را برای کاربران خود در یک دامنه یکتا ایجاد کنیم.

برای استفاده از پلتفرم احراز هویت Auth0 برای ورود، بیایید یک برنامه جدید از نوع “برنامه وب معمولی” را با دنبال کردن این لینک ایجاد کنیم.

از لیست فناوری‌ها، لطفاً Java Spring Boot را انتخاب کنید.

پس از ایجاد برنامه، شما می‌توانید به جزئیات برنامه بروید تا clientId و clientSecret را دریافت کنید.

همچنین، لطفاً URLهای Callback مجاز خود را به‌روزرسانی کنید.

http://localhost:8080/login/oauth2/code/

لطفاً توجه کنید که لازم نیست URI ورود برنامه را به‌روزرسانی کنید.

در بخش جزئیات پیشرفته، شما قادر خواهید بود تمام URLهای مورد نیاز (نقاط پایان) برای پیکربندی OAuth 2.0 را پیدا کنید.

پیکربندی ThingsBoard

حالا می‌توانیم یک تامین کننده دیگر را اضافه کنیم:

سپس گزینه “سفارشی” را انتخاب کنید.

لطفاً اطلاعات (client ID و client secret) را از جزئیات برنامه خود ارائه دهید و می‌توانید تمام URLهای مورد نیاز را در بخش جزئیات پیشرفته پیدا کنید.

در فیلد روش احراز هویت مشتری، گزینه “POST” را انتخاب کنید. در فیلد برچسب تامین کننده، Auth0 را مشخص کنید. سپس چک باکس “اجازه ایجاد کاربر” را علامت بزنید. به فیلد دامنه‌های نمونه اضافه کنید: openid، email، profile. و به بلاک Mapper بروید.

نوع “پایه” را انتخاب کنید و در صورت لزوم فیلدها را پر کنید (که در بخش Basic mapper این مقاله به طور دقیقتر توضیح داده شده است). برخی از تنظیمات فقط در نسخه حرفه‌ای (Professional Edition) در دسترس هستند. سپس تنظیمات را ذخیره کنید.

با این تنظیمات، تنظیمات oauth2 برای Auth0 به شکل زیر خواهد بود.

اگر به صفحه ورود برویم، دو گزینه ورود ممکن را خواهیم دید – Google و Auth0:

وقتی بر روی آن کلیک کنیم و حساب Auth0 خود را انتخاب کنیم، وارد ThingsBoard می‌شویم و با استفاده از ایمیل خود به عنوان کاربر مشتری وارد می‌شویم.

اگر به عنوان مدیر سیستم وارد شوید، خواهید دید که نام مستاجر برابر با دامنه ایمیل Auth0 ماست، طبق تنظیمات پایه (basic mapper).

ما نمونه خود را کامل کرده‌ایم و اکنون کاربران شما نیازی به ایجاد حساب در داخل ThingsBoard ندارند – آنها می‌توانند از تامین کننده‌های SSO موجود برای این کار استفاده کنند.

کد نمونه حاصل

این کد حاوی هر دو تامین کننده است که در نمونه ما استفاده شده است:

نگاشت کاربر خارجی به ساختار کاربر داخلی ThingsBoard

نگاشت شیء اطلاعات کاربر خارجی به کاربر ThingsBoard می‌تواند به دو روش – استفاده از نگاشت‌های پایه و سفارشی – انجام شود. عملکرد اصلی نگاشت‌کننده این است که ویژگی‌های کلید-مقدار را از شیء اطلاعات کاربر خارجی به ساختار مورد انتظار کاربر OAuth 2.0 ThingsBoard نگاشت کند:

public class OAuth2User {
    private String tenantName;
    private TenantId tenantId;
    private String customerName;
    private CustomerId customerId;
    private String email;
    private String firstName;
    private String lastName;
    private boolean alwaysFullScreen;
    private String defaultDashboardName;
    
    // NOTE: Next configurations available only in Professional Edition

    private List<String> userGroups;
    private String parentCustomerName;
    private CustomerId parentCustomerId;
}

نگاشت پایه (Basic mapper)

نگاشت پایه قادر است یک شیء اطلاعات کاربر OAuth 2.0 خارجی را با یک مجموعه قوانین پیش‌تعیین شده، با یکدیگر ترکیب کند و به یک کاربر OAuth 2.0 ThingsBoard تبدیل کند.

برای استفاده از یک نگاشت پایه، لطفاً mapperConfig.type یا متغیر محیطی SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE را به basic تنظیم کنید.

در زیر جزئیات دیگر ویژگی‌ها آمده است:

  • allowUserCreation – اگر این گزینه به true تنظیم شود، در صورتی که حساب کاربری هنوز در ThingsBoard وجود نداشته باشد، آن را ایجاد خواهد کرد. اگر این گزینه به false تنظیم شود، کاربر در صورت تلاش برای ورود با تامین کننده OAuth 2.0 خارجی اما بدون وجود کاربر در ThingsBoard با این مشخصات، خطای دسترسی رد خواهد شد.
  • emailAttributeKey – این کلید برای ویژگی‌های شیء اطلاعات کاربر OAuth 2.0 خارجی است که به عنوان خاصیت ایمیل کاربر ThingsBoard استفاده می‌شود.
  • firstNameAttributeKey – این کلید برای ویژگی‌های شیء اطلاعات کاربر OAuth 2.0 خارجی است که به عنوان خاصیت نام کوچک کاربر ThingsBoard استفاده می‌شود.
  • lastNameAttributeKey – این کلید برای ویژگی‌های شیء اطلاعات کاربر OAuth 2.0 خارجی است که به عنوان خاصیت نام خانوادگی کاربر ThingsBoard استفاده می‌شود.
  • tenantNameStrategy – این گزینه مشخص می‌کند کدام مستاجر برای ایجاد کاربر انتخاب می‌شود. یک نگاشت پایه سه گزینه استراتژی ممکن برای تولید نام مستاجر از یک شیء اطلاعات کاربر خارجی را ارائه می‌دهد: domain، email یا custom:
    • domain: نام مستاجر به عنوان دامنه ایمیل کاربر استخراج می‌شود.
    • email: نام مستاجر برابر با ایمیل کاربر خواهد بود.
    • custom: می‌توان الگوی سفارشی برای نام مستاجر تعیین کرد. لطفاً tenantNamePattern را مشاهده کنید.
  • tenantNamePattern – در صورت استفاده از tenantNameStrategy به عنوان custom، می‌توانید نام مستاجری که کاربر در آن ایجاد خواهد شد را با استفاده از یک الگوی سفارشی مشخص کنید. می‌توانید از ویژگی‌های شیء اطلاعات کاربر خارجی برای قرار دادن آنها در نام مستاجر استفاده کنید. لطفاً از %{attribute_key} به عنوان جایگزین برای مقدار ویژگی استفاده کنید.

مثال‌های الگوی مستاجر:

    •  Demo Tenant: نام مستاجر ثابت
    •  Demo Tenant %{email}: اگر ایمیل کاربر test@demo.com باشد، نام مستاجر ‘Demo Tenant test@demo.com’ خواهد بود.
    •  %{givenName}: اگر ویژگی givenName کاربر Demo User باشد، نام مستاجر ‘Demo User’ خواهد بود.
  • customerNamePattern – اگر این فیلد الگوی مشتری خالی نباشد، کاربر زیر یک مشتری خاص و نه مستاجر ایجاد می‌شود. می‌توانید از ویژگی‌های شیء اطلاعات کاربر خارجی برای قرار دادن آنها در نام مشتری استفاده کنید. لطفاً از %{attribute_key} به عنوان جایگزین برای مقدار ویژگی استفاده کنید.

مثال‌های الگوی مشتری:

  •  Demo Customer: نام مشتری ثابت
  •  Demo Customer %{email}: اگر ویژگی ایمیل کاربر test@demo.com باشد، نام مشتری ‘Demo Customer test@demo.com’ خواهد بود.
  •  %{city}: اگر ویژگی city کاربر New York باشد، نام مشتری ‘New York’ خواهد بود.
  • defaultDashboardName – اگر این فیلد خالی نباشد، کاربر به یک داشبورد خاص هدایت خواهد شد.
  • alwaysFullScreen – اگر این فیلد true باشد و defaultDashboardName خالی نباشد، کاربر به یک داشبورد خاص به صورت تمام صفحه هدایت خواهد شد.
  • parentCustomerNamePattern

(تنها در نسخه حرفه‌ای (Professional Edition) در دسترس است)

اگر این فیلد الگوی نام مشتری والد مشتری را تعیین کند، می‌توان مشتری کاربر را در سلسله مراتب تحت این مشتری والد ایجاد کرد. می‌توانید از ویژگی‌های شیء اطلاعات کاربر خارجی برای قرار دادن آنها در نام مشتری والد استفاده کنید. لطفاً از %{attribute_key} به عنوان جایگزین برای مقدار ویژگی استفاده کنید.

مثال‌های الگوی مشتری والد:

  •  Demo Parent Customer: نام مشتری والد ثابت
  •  Demo Parent Customer %{email}: اگر ویژگی ایمیل کاربر test@demo.com باشد، نام مشتری والد ‘Demo Parent Customer test@demo.com’ خواهد بود.
  •  %{country}: اگر ویژگی کشور کاربر Top Customer باشد، نام مشتری والد ‘Parent Customer’ خواهد بود.

userGroupsNamePattern – (تنها در نسخه حرفه‌ای (Professional Edition) در دسترس است) به طور پیش فرض، کاربری که تازه ایجاد شده است تنها به گروه کاربران All اختصاص می‌یابد. شما می‌توانید این رفتار را سفارشی کنید با مشخص کردن لیستی از گروه‌ها که کاربر همچنین باید به آنها اختصاص داده شود. می‌توانید از ویژگی‌های شیء اطلاعات کاربر خارجی برای قرار دادن آنها در نام گروه‌های کاربر استفاده کنید. لطفاً از %{attribute_key} به عنوان جایگزین برای مقدار ویژگی استفاده کنید. اگر گروه‌ها وجود نداشته باشند، این گروه‌ها به طور خودکار ایجاد خواهند شد.

مثال‌های الگوی گروه‌های کاربر:

  •  Tenant Administrators, Managers: گروه‌های کاربر ثابت
  •  %{job_title}: اگر ویژگی job_title کاربر Manager باشد، کاربر در گروه کاربر Manager قرار خواهد گرفت.

نقشه بردار سفارشی

اگر عملکرد اصلی نقشه‌بردار نیازهای کسب‌وکار شما را پوشش نمی‌دهد، با کمک نقشه‌بر سفارشی می‌توانید پیاده‌سازی متناسب با اهداف خاص خود را اضافه کنید.

یک نقشه‌بردار سفارشی که به‌عنوان یک میکروسرویس جداگانه طراحی شده است که در نزدیکی میکروسرویس اصلی ThingsBoard اجرا می‌شود. ThingsBoard همه درخواست‌های نقشه‌برداری را به این میکروسرویس ارسال می‌کند و به عنوان یک پاسخ، شی کاربر ThingsBoard OAuth 2.0 را انتظار دارد:

public class OAuth2User {
    private String tenantName;
    private TenantId tenantId;
    private String customerName;
    private CustomerId customerId;
    private String email;
    private String firstName;
    private String lastName;
    private boolean alwaysFullScreen;
    private String defaultDashboardName;
    
    // NOTE: Next configurations available only in Professional Edition
    private List<String> userGroups;
    private String parentCustomerName;
    private CustomerId parentCustomerId;
}

لطفاً به این پیاده‌سازی پایه به عنوان نقطه شروع برای نقشه‌بردار سفارشی خود مراجعه کنید.

برای استفاده از نگاشت سفارشی، لطفا mapperConfig.type یا متغیر محیطی SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE را روی سفارشی تنظیم کنید.

در اینجا جزئیات سایر املاک آمده است:

URL

URL نقطه پایانی نگاشت سفارشی.

نام کاربری

اگر نقطه پایانی نگاشت سفارشی با مجوز اولیه پیکربندی شده است، نام کاربری را در این ویژگی مشخص کنید.

کلمه عبور

اگر نقطه پایانی نگاشت سفارشی با مجوز اولیه پیکربندی شده است، رمز عبور را در این ویژگی مشخص کنید.

در اینجا یک نمونه از پیکربندی دمو آورده شده است:

custom:
    url: http://localhost:10010/oauth2/mapper
    username: admin
    password: pa$$word

پارامترهای پیکربندی OAuth 2.0


Key


Description



security.oauth2.enabled


Enable/disable OAuth 2.0 login functionality



security.oauth2.loginProcessingUrl

Redirect URL where access code from
external user management system will be processed



security.oauth2.clients.default.loginButtonLabel

Label that
going to be show on login button – ‘Login with {loginButtonLabel}’



security.oauth2.clients.default.loginButtonIcon

Icon that going to be show on login
button. Material design icon ID. List of icon IDs could be found here



security.oauth2.clients.default.clientName

Logical
name of the client or registration



security.oauth2.clients.default.clientId

Client ID



security.oauth2.clients.default.clientSecret

Client
secret



security.oauth2.clients.default.accessTokenUri

URI for the token endpoint



security.oauth2.clients.default.authorizationUri

URI for the
authorization endpoint



security.oauth2.clients.default.scope

Sets the scope(s) used for the
client



security.oauth2.clients.default.redirectUriTemplate

URI (or uri
template) for the redirection endpoint. Must be in sync with
‘security.oauth2.loginProcessingUrl’ (domain name added)



security.oauth2.clients.default.jwkSetUri

URI for the JSON Web Key (JWK) Set
endpoint



security.oauth2.clients.default.authorizationGrantType



Authorization grant type
 used for the client



security.oauth2.clients.default.clientAuthenticationMethod



Authentication method
 used when authenticating the
client with the authorization server



security.oauth2.clients.default.userInfoUri

URI for the
user info endpoint



security.oauth2.clients.default.userNameAttributeName

Attribute name used to access the
user’s name from the user info response

پیکربندی HaProxy

اگر ThingsBoard تحت یک متعادل کننده بار مانند HAProxy اجرا می شود، لطفاً الگوریتم تعادل را به درستی پیکربندی کنید تا مطمئن شوید که جلسه صحیح در نمونه ThingsBoard موجود است:

backend tb-api-backend
  ...
  balance source # balance must be set to 'source'
  ...

همچنین لطفاً نگاشت ACL را برای درخواست های HTTP و HTTP به درستی پیکربندی کنید:

frontend http-in
  ...
  acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
  ...
frontend https_in
  ...
  acl tb_api_acl path_beg /api/ /swagger /webjars /v2/ /static/rulenode/ /oauth2/ /login/oauth2/ # '/oauth2/ /login/oauth2/' added
  ...

عناوین هر بخش