15- دسترسی ها و مجوزها در اندروید
آدرس مطلب اصلی: http://developer.android.com/guide/topics/security/permissions.html
در این سند موارد زیر بحث خواهد شد
1. معماری امنیت
2. امضای برنامه
3. شناسه کاربری و دسترسی به فایل
4. استفاده از مجوز
5. درخواست مجوزهای اجباری :
الف) در AndroidManifest.xml
ب) در هنگام ارسال برنامههای پخش شدنی
ج) دیگر عوامل اجباری در مجوزها
6. مجوزهای URI
مجوزهای سیستم
آندروید یک سیستم عامل با قابلیت مجزا سازی است که در آن هر برنامه با هویت مجزا اجرا میشود (ID کاربر لینوکس و ID گروهی). همچنین بخشهایی از سیستم نیز هویت های متمایز دارند. در نتیجه لینوکس برنامه های کاربردی را از یکدیگر و از سیستم جدا میکند.
ویژگیهای امنیتی ریز اضافی از طریق مکانیزم "مجوز" مهیا شده است که محدودیتهایی در اجرای عملیاتهای خاص که میتواند در یک فرآیند مخصوص انجام شود ایجاد میکنند، و همچنین این ویژگیها در مجوزهای هر URI برای دادن دسترسی موقت به بخش خاصی از دادهها محدودیت ایجاد میکنند.
این سند شرح میدهد که چگونه سازندگان نرم افزار میتوانند از ویژگیهای امنیتی ارائه شده توسط آندروید استفاده کنند. اطلاعات عمومی بیشتر در مورد امنیت آندروید در آرشیو پروژه آندروید اوپن سورس وجود دارد
ساختار امنیت
نقطه ذظر اصلی طراحی معماری امنیتی آندروید این است که هیچ برنامه، بهطور پیش فرض است، اجازه انجام هرگونه عملیات که تاثیر منفی روی برنامههای کاربردی دیگر، سیستم عامل، و یا کاربر را داشته باشد را نمیدهد. این شامل خواندن و نوشتن اطلاعات خصوصی کاربر ( مانند اطلاعات تماس یا ایمیل)، خواندن و نوشتن فایلهای برنامههای دیگر و انجام دسترسی به شبکه، نگهداری بیدار دستگاه، و غیره میباشد.
از آنجا که هر برنامه آندروید در یک فرایند sandbox کار میکند، برنامههای کاربردی باید منابع و اطلاعات را به اشتراک بگذارند. آنها این کار را با درخواست مجوز برای داشتن قابلیتهای اضافه که توسط sandbox عمومی ارائه نشده است انجام میدهند. برنامهها مجوز مورد نیاز را به صورت استاتیکی درخواست میکنند و سیستم آندروید کاربر را در زمان نصب برنامه برای رضایت از این موضوع مطلع می کند. آندروید هیچ مکانیزمی برای اعطای مجوز به صورت پویا (در زمان اجرا) نمیدهد چون این باعث پیچیده شدن کار کاربر و به ضرر امنیت است.
sandbox یک برنامه بستگی به تکنولوژی استفاده شده برای ساخت آن برنامه ندارد. بهطور خاص DALVIK VM یک مرز امنیتی نیست، و هر برنامهای میتواند کد اصلی (native) اجرا کند (نگاه کنید به آندروید NDK ). همه نوع از برنامههای کاربردی - جاوا، بومی و هیبرید - با یک روش ساندباکس شده اند و درجه امنیت آنها یکسان است.
امضای برنامه
همه APK ها ( فایلهای APK ) باید با یک گواهی که رمز آن پیش سازندگان است امضا شوند. این گواهی نویسنده نرم افزار را شناسایی میکند. گواهی نیازی به امضای مراجع معتبر ندارند بلکه میتوان برای برنامههای کاربردی آندروید از گواهیهای خود معتبر استفاده کرد که کاملا مجاز و معمول هستند. هدف از گواهی در آندروید این است که سازندگان برنامه کاربردی مشخص شوند. این اجازه میدهد تا سیستم دسترسی به برنامههای کاربردی به مجوزهای در سطح امضا را رد یا قبول کند و همچنین اجازه میدهد تا به درخواست یک برنامه برای گرفتن هویت لینوکس یک برنامه دیگر پاسخ رد یا قبول دهد.
شناسه کاربری و دسترسی به فایل
در زمان نصب، آندروید به طور جداگانه یک شناسه کاربری لینوکس به هر پکیج میدهد. این هویت در تمام طول عمر دستگاه در پکیج ثابت میماند. در یک دستگاه متقاوت، همان پکیج ممکن است UID های متقاوتی داشته باشد؛ آنچه مهم است این است که هر پکیج دارای یک UID مجزا در هر دستگاه است.
از آنجا که ملزومات امنیت در سطح فرآیند اتفاق می افتند، کد هیچ دو پکیجی در یک فرایند مشترک اجرا نمیشود، چرا که میبایست آنها به عنوانهای کاربرهای مختلف لینوکس اجرا شوند. شما میتوانید ویژگی sharedUserId را در برچسب آشکارساز AndroidManifest.xml هر پکیج استفاده کنید تا یک شناسه کاربری مشترک به آنها اختصاص دهید. با انجام این کار، برای اهداف امنیتی دو پکیج به عنوان یک برنامه شناخته میشوند که ID و مجوزهای فایل یکسانی دارند. توجه داشته باشید که به منظور حفظ امنیت، تنها به دو برنامههای کاربردی امضا شده با امضای یکسان یک ID مشترک داده میشود.
هر گونه دادههای ذخیره شده توسط نرم افزار اختصاص داده خواهد شد به یک شناسه کاربری و بهطور معمول در دسترس پکیجهای دیگر قرار نخواهد گرفت. هنگام ایجاد یک فایل جدید با
getSharedPreferences (String, int)
یا
openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory)
شما میتوانید از فلگهای
MODE_WORLD_READABLE
و یا
MODE_WORLD_WRITEABLE
استفاده کنید تا اجازه دهید به پکیجهای دیگر که فایل را بخوانند یا بنویسند (write). هنگام تنظیم این پرچمها، فایل هنوز متعلق به برنامه شماست، اما مجوز خواندن و یا نوشتن عمومی برای هر برنامهای که آن را بتواند ببیند صادر شده است.
مجوز استفاده
یک برنامه پایه آندروید هیچگونه مجوزی بهطور پیش فرض ندارد، به این معنی که آن نمیتواند هیچ تأثیر منفی روی کار کاربر و یا روی اطلاعات بر روی دستگاه داشته باشد. برای استفاده از ویژگیهای محافظت از دستگاه، شما باید در AndroidManifest.xml خود یک یا چند برچسب <uses-permission> برای گرفتن مجوزهایی که برنامه شما نیاز دارد استفاده کنید.
به عنوان مثال، یک برنامه که نیاز به نظارت بر پیامهای SMS های دریافتی دارد برچسبهای زیر را میخواهد :
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> ... </manifest>
در زمان نصب برنامه ، مجوزهای لازم توسط نصب کننده به آن داده میشود. البته مجوزهایی که بر اساس امضا (قرارداد) برنامه میتوان درخواست داد و یا مجوزهایی که کاربر میتواند با برنامه ارتباط دو طرفه داشته باشد. وقتی یک برنامه در حال اجرا است هیچ بررسی بر روی کاربر انجام نمیشود. همچنین یک اپلیکیشن زمانی مجوز میگیرد که نصب شده باشد و بتواند از آن ویژگی به صورت مطلوب استفاده کند. یا اینکه کلا هیچ مجوزی داده نمیشود و هر تلاشی برای استفاده از فیچرهای برنامه بیفایده خواهد بود.
اغلب اوقات یک مشکل مجوز منجر به SecurityException (استثنای امنیتی) میشود که به برنامه اعمال میشود. با این حال، این اتفاق هر جایی صورت نمیپذیرد. به عنوان مثال، روش sendBroadcast( Intend ) مجوزها را چک میکند که اطلاعات به گیرندهها تحویل داده شده است، اگر مشکل مجوز وجود داشته باشد شما یک پیغام خطا دریافت خواهید کرد. تقریبا در همه موارد یک مشکل مجوز در لاگ سیستم چاپ خواهد شد.
با این حال، در یک وضعیت کاربر معمولی ( مانند زمانی که برنامه از Google Play Store نصب شده باشد) ، نرم افزار نمیتواند نصب شود اگر کاربر مجوزهای لازم نرم افزار را نداشته باشید. بنابراین شما به طور کلی لازم نیست که نگران خطای زمان اجرا باشید که به دلیل نبود مجوز رخ داده است. به خاطر اینکه برنامهای که نصب شده میبایست مجوزهای لازم را داشته باشد.
مجوزهای ارائه شده توسط سیستم عامل Android را میتوان در Manifest.permission یافت. هر برنامه نیز ممکن است مجوزهای خواص خود را لازم داشته باشد، پس این یک لیست جامع از همه مجوزهای لازم نیست.
* در حین اجرای برنامه شما یک مجوز خاص ممکن است در تعدادی از نقاط کار کند:
* در زمان فراخوانی سیستم، برای جلوگیری از یک برنامه از اجرای عملکردهای خاص.
* هنگامی که شروع یک فعالیت، برای جلوگیری از راهاندازی کار برنامههای دیگر.
* در ارسال و دریافت پخش برنامه، کنترل می کند چه کسی میتواند پخش شما را دریافت و یا چه کسی میتواند پخش خود را برای شما ارسال کند.
* هنگام دسترسی و اجرای برنامه بر روی محتویات مهیا کننده (سرور).
* زمان اتصال و یا شروع یک سرویس.
توجه: با گذشت زمان، ممکن است محدودیتهای جدید به پلت فرم اضافه شود بهطوری که، به منظور استفاده از API های خاص، برنامه شما مجوزی درخواست کند که قبلا نیازی نداشت. از آنجا که فرض می شود برنامههای موجود دسترسی آزادی به API ها دارند، آندروید ممکن است درخواست مجوز جدید برای آشکارسازی برنامه نماید که برای جلوگیری از خرابی برنامه در نسخه جدید پلت فرم است. آندروید تصمیم می گیرد که آیا یک برنامه ممکن است احتیاج به مجوز بر اساس ارزش ارائه شده برای ویژگی targetSdkVersion داشته باشد یا خیر. اگر ارزش پایین تر از نسخههای باشد که در آن مجوز اضافه شده است ، آندروید مجوز را اضافه میکند.
بهعنوان مثال، مجوز WRITE_EXTERNAL_STORAGE در سطح API 4 برای محدود کردن دسترسی به فضای ذخیره سازی مشترک اضافه شده است. اگر targetSdkVersion شما 3 و یا کمتر است، این مجوز به برنامه شما در نسخه های جدیدتر آندروید اضافه می شود.
مراقب باشید که اگر این اتفاق برای برنامه شما بیافتد، لیست برنامه های شما در Google Play مجوزهای لازم را نشان می دهد حتی اگر برنامه شما ممکن است به آنها واقعا نیاز نداشته باشد.
برای جلوگیری از این موضوع و حذف مجوزهای پیش فرض شما لازم نیست ، همیشه targetSdkVersion خود را به روز رسانی کنید. شما میتوانید ببینید که چه مجوزهایی را در هر نسخه در اسناد Build.VERSION_CODES اضافه شدهاند.
درخواست و اجرای مجوزها
برای اجرای مجوزهای خود، شما باید اول آنها را در AndroidManifest.xml خود با یک یا چند برچسب <permission> فراخوانی کنید.
به عنوان مثال ، یک برنامه ای که می خواهد کنترل کند چه کسی می تواند یکی از فعالیت های خود را شروع کند، می تواند یک مجوز برای این عملیات به شرح زیر اعلام کند:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.app.myapp" >
<permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
ویژگی <protectionLevel> مورد نیاز است برای گفتن این که سیستم چگونه کاربر را مطلع میسازد که برنامه ها به مجوز احتیاج دارند و یا چه کسی مجاز به داشتن مجوز است، این موارد در اسناد پیوست شده تشریح شدهاند.
ویژگی <permissionGroup> اختیاری است، و تنها برای کمک به نمایش مجوز سیستم به کاربر میباشد. شما معمولا می خواهید این را به صورت گروه سیستم استاندارد ( ذکر شده در android.Manifest.permission_group ) تنظیم نمایید و یا به صورت نادر خودتان تعریف کنید. ترجیح داده میشود که از یک گروه موجود استفاده شود، چرا که نمایش UI برای کاربر ساده تر میکند.
توجه داشته باشید که هر دو برچسب و شرح باید برای مجوز عرضه شده باشد. اینها منابع رشتهای هستند که میتوانند به کاربر نمایش داده شوند زمانی که آنها درحال دیدن لیستی از مجوزها )android:label) یا جزییات یک مجوز (android:description) هستند. یک برچسب باید کوتاه باشد، چند کلمه برای توصیف قسمت اصلی قابلیت مجوز. توضیحات باید چند جمله توصیفی از آنچه که مجوز اجازه میدهد تا دارنده آن انجام دهد باشد. قرار ما برای توصیفات دو جمله است، اولی توصیف کننده مجوز، و دومی اخطار به کاربر در مورد اینکه چه اتفاق بدی می تواند بیافتد اگر یک برنامه دارای مجوز شود.
در اینجا یک مثال از یک برچسب و توضیح
برای مجوز CALL_PHONE وجود دارد:
<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the application to call
phone numbers without your intervention. Malicious applications may
cause unexpected calls on your phone bill. Note that this does not
allow the application to call emergency numbers.</string>
<string name="permlab_callPhone"> شماره تلفن تماس مستقیم
<string name="permdesc_callPhone"> اجازه میدهد تا برنامه بدون دخالت شما بهشماره تلفنی تماس بگیرد. برنامههای مضر ممکن باعث تماسهای غیر منتظره شوند. توجه داشته باشید که این اجازه نمیدهد تا برنامه به شمارههای اضطراری تماس بگیرد.
شما میتوانید نگاه کنید به مجوزهایی که در حال حاضر در سیستم با اپلیکیشن Settings و فرمان پوسته adb shell pm list permissions تعریف شدهاند. برای استفاده از اپلیکیشن Settings بروید Settings > Applications. . یک اپلیکیشن انتخاب کنید و به پایین حرکت کنید تا مجوزهای آن را ببینید. برای سازندگان، گزینه adb '-s' مجوزها را در یک فرم شبیه به نحوه دیده شده برای کاربر نشان می دهد:
$ adb shell pm list permissions -s
All Permissions:
Network communication: view Wi-Fi state, create Bluetooth connections, full
Internet access, view network state
Your location: access extra location provider commands, fine (GPS) location,
mock location sources for testing, coarse (network-based) location
Services that cost you money: send SMS messages, directly call phone numbers
...
اجرای مجوز ها در AndroidManifest.xml
مجوزهای سطح بالا دسترسی به تمام اجزای سیستم و یا برنامه ای که می تواند از طریق AndroidManifest.xml شما اجرا شود را محدود می کند. تمام چیزی که این نیاز دارد در ویژگی android:permission بر روی یک قطعه مطلوب وجود دارند، این قطعه طوری نام گذاری شده است که نشان دهنده مجوزی است که استفاده می شود برای کنترل دسترسی به آن.
مجوزهای Activity ( اعمال شده به برچسب <activity> ) کسی را محدود میکند که میتواند فعالیتهای مرتبطی را شروع کند. مجوز در طول Context.startActivity)) و Activity.startActivityForResult)) بررسی میشود؛ در صورتی که درخواست کننده مجوز لازم را نداشته باشد SecurityException از تماس (یا فراخوانی) خارج می شود.
مجوزهای Service ( اعمال شده به برچسب <service> ) کسی را محدود میکند که میتواند فعالیتهای مرتبطی را شروع کند یا پیوند بزند. مجوز در طول (Context.startService)، (Context.stopService) و (Context.bindService) بررسی میشود؛ در صورتی که درخواست کننده مجوز لازم را نداشته باشد SecurityException از تماس (یا فراخوانی) خارج میشود.
مجوزهای BroadcastReceiver ( اعمال شده به برچسب <receiver> ) کسی را محدود میکند که میتواند پخش برنامه را به گیرنده مرتبطی ارسال کند. مجوز پس از بازگشت (Context.sendBroadcast) بررسی میشود، زمانی که سعی می کند برنامه پخش را به یک گیرنده بفرستد. در نتیجه، یک خطای مجوز منجر به پیامی نمیشود که به تماس گیرنده برگشت داده شود؛ تنها این برنامه است که به گیرنده مد نظر ارائه نخواهد شد. به همان صورت، یک مجوز میتواند به (Context.registerReceiver) داده شود برای کنترل کسی که میتواند به یک گیرنده محدود شده با برنامه نویسی شده برنامه پخشی بفرستد. از طرف دیگر، مجوز زمانی میتواند داده شود که (Context.sendBroadcast) فراخوانی می شود تا ابجکتهای BroadcastReceiver که مجاز به دریافت پخش هستند را محدود کند (پایین را ببینید).
مجوزهای ContentProvider (اعمال شده به برچسب <provider>) کسی را محدود میکند که میتواند دسترسی داشته باشد به دادهها در ContentProvider. (ارائه دهندگان محتوا امکانات امنیتی اضافی مهمی دارند که در دسترس آنهایی است که با URI permissions نام گذاری شده اند. بعدا درمورد آنها شرح داده می شود). بر خلاف اجزای دیگر، دو ویژگی جدا برای مجوز وجود دارد که شما می توانید ست کنید: android:readPermission کسی را محدود می کند که می تواند داده ها را از ارائه دهنده بخواند android:writePermission کسی را محدود می کند که می تواند در آن بنویسد. توجه داشته باشید که اگر یک ارائه دهنده با هر دو مجوز خواندن و نوشتن محافظت شود، فقط داشتن مجوز نوشتن به این معنا نیست که شما می توانید از یک ارائه دهنده بخوانید. وقتی شما اولین بار به ارائه دهنده متصل می شوید (اگر شما هر دو مجوز را مدارید ،SecurityException رخ می دهد )، و یا وقتی شما عملیاتی را بر روی ارائه دهنده انجام می دهید مجوز ها چک می شوند. برای استفاده از ContentResolver.query)) نیاز به داشتن مجوز خواندن است. برای استفاده از ContentResolver.insert) )، ContentResolver.update))، ContentResolver.delete)) نیاز به مجوز نوشتن است. در تمام این موارد، نداشتن مجوز منجر به SecurityException میشود.
اجرای مجوزها در هنگام ارسال برنامههای پخش شدنی (Broadcast)
علاوه بر مجوزی که مشخص میکند چه کسی میتواند به BroadcastReceiver چیزی بفرستد (در بالا توضیح داده شد)، شما همچنین میتوانید مجوز مورد نیاز در هنگام ارسال پخش را مشخص کنید. با فراخوانی (Context.sendBroadcast) با یک رشته مجوز، نیاز است که نرم افزار گیرنده یک مجوز به منظور دریافت پخش داشته باشد.
توجه داشته باشید که هر دو یک گیرنده و فرستنده میتوانند مجوز نیاز داشته باشند. هنگامی که این اتفاق میافتد، بررسی هر دو مجوز بایستی مثبت باشند تا برنامه مد نظر پخش به مقصد ارسال شود.
اجرای دیگر مجوزها
مجوزهای قراردادی کوچک میتوانند در هر فراخوانی داخل سرویس اجرا شوند. این با استفاده از روش (Context.checkCallingPermission) انجام میشود. شما فراخوانی کنید با یک رشته مجوز مورد نظر و آن یک عدد صحیح برمیگرداند که نشان میدهد آیا این مجوز به روند فراخوانی فعلی اعطا شده است یا نه. توجه داشته باشید که این تنها میتواند زمانی استفاده شود که شما یک فراخوانی را اجرا میکنید که از فرآیند دیگر میآید، معمولا از طریق یک رابط IDL منتشر شده از یک سرویس و یا به طریقی به فرایند دیگری داده میشود.
تعدادی از دیگر راههای مفید برای بررسی مجوز دسترسی وجود دارند. اگر شما PID پروسههای دیگر را داشته باشید، میتوانید از روش زمینه Context.checkPermission (String, int, int) برای بررسی مجوز در برابر آن PID استفاده کنید. اگر شما نام مجموعهای از برنامههای دیگر را دارید، میتوانید از روش PackageManager مستقیم PackageManager.checkPermission(String, String) برای فهمیدن این که آیا این بستهبندی خاص دارای مجوز خاص میباشد.
مجوزهای URI
سیستم مجوز استانداردی که تا کنون شرح داده شد اغلب کافی نیست وقتی که با تامین کنندگان محتوا استفاده میشود. ارائه دهنده محتوا ممکن است بخواهد از خود با مجوز خواندن و نوشتن محافظت کند، در حالی که مشتریان مستقیم آن نیز نیاز دارند به دادن URI های خاص به یک برنامه دیگر برای کار به روی آنها. به عنوان نمونه فایل پیوست در یک برنامه پست الکترونیکی را میتوان نام برد. دسترسی به پست الکترونیکی باید با مجوز محافظت انجام شود، چون این داده حساس کاربر است. با این حال، اگر یک URI به پیوست تصویر یک نمایشگر تصویر داده شده است، آن نمایشگر تصویر مجوز باز کردن فایل پیوست نخواهد داشت چون هیچ دلیلی برای داشتن یک مجوز برای دسترسی به تمام ایمیل ندارد.
راه حل این مشکل مجوز برای هر URI است: در هنگام شروع یک فعالیت و به نتیجه رسیدن یک فعالیت، تماس گیرنده میتواند Intent.FLAG_GRANT_READ_URI_PERMISSION و / یا Intent.FLAG_GRANT_WRITE_URI_PERMISSION را تنظیم کند. این مجوز فعالیت دریافت اطلاعات را برای دسترسی به دادههای خواص از URI در مقصد را میدهد بدون در نظر گرفتن که آیا آن مجوز دسترسی به اطلاعات ارائه دهنده محتوا دارد یا خیر.
این مکانیزم اجازه میدهد تا یک مدل مشترک قابلیت ـ سبک که در آن تعامل با کاربر ( باز کردن یک پیوست، انتخاب یک تماس از یک لیست، و غیره) باعث دادن مجوز ریز میشود. این میتواند یک امکان کلیدی برای کاهش مجوز مورد نیاز توسط برنامههای کاربردی شود یعنی مجوز تنها به آنهایی که به طور مستقیم به رفتار آنها مربوط میشود داده میشود.
با این حال اعطای مجوزهای URI ریز نیاز به همکاری با ارائه دهنده محتوا دارد که URI ها را نگه میدارند. به شدت توصیه میشود که ارائه دهندگان محتوا این امکانات را پیاده سازی کنند، و اعلام کنند که آنها پشتیبانی میکنند از طریق ویژگی android:grantUriPermissions یا برچسب <grant-uri-permissions>.
اطلاعات بیشتر در روشهای
(Context.grantUriPermission) ,(Context.revokeUriPermission)
و
یافت میشود.- ۹۳/۰۳/۰۲
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.