متن خبر

نحوه پیاده سازی یک سرور منبع OAuth2 با امنیت Spring

نحوه پیاده سازی یک سرور منبع OAuth2 با امنیت Spring

شناسهٔ خبر: 470134 -




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

هنگامی که API های خود را برنامه ریزی کردید، یک مرحله مهم وجود دارد که باید از آن مراقبت کنید: ایمن سازی API های خود. شما نمی خواهید API های خود را در معرض دید کسی در اینترنت قرار دهید (مگر اینکه برای منبع باز بسازید).

احراز هویت تضمین می کند که API های شما فقط توسط کاربران تأیید شده برنامه شما قابل دسترسی است. یک کاربر را می توان با نام کاربری و رمز عبور یا از طریق نشانه دسترسی احراز هویت کرد.

در این پست، ما قصد داریم ببینیم که چگونه API های خود را با استفاده از OAuth2 و توکن های دسترسی ایمن کنید. من فرض می کنم که شما دانش اولیه جاوا و Spring Boot را دارید. اگر نه، می‌توانید این دوره را در کانال YouTube FreeCodeCamp تحلیل کنید .

فهرست مطالب

    OAuth2 چیست؟

    نحوه راه اندازی اپلیکیشن Spring Boot

    پیکربندی امنیت وب

    APIهای عمومی و خصوصی

    تست APIها با و بدون Access Token

    نحوه دریافت اطلاعات کاربر از توکن Access

OAuth2 چیست؟

OAuth2 چارچوبی است که به برنامه های شخص ثالث اجازه می دهد از طرف یک کاربر نهایی به سرویس شما دسترسی داشته باشند. این به طور گسترده ای برای احراز هویت و مجوز در برنامه های مدرن استفاده می شود.

چهار جزء در چارچوب OAuth2 وجود دارد:

مالک منبع : کاربر نهایی برنامه شما.

سرور مجوز : برنامه شخص ثالثی که کاربر را احراز هویت می کند و پس از احراز هویت موفق، یک رمز دسترسی صادر می کند.

Client : رابط کاربری که کاربر می خواهد از طریق آن به منابع شما دسترسی داشته باشد. مشتری می تواند یک برنامه تلفن همراه، برنامه وب یا یک برنامه دسکتاپ باشد. کلاینت برای دسترسی به API های شما به یک نشانه دسترسی نیاز دارد.

سرور منبع : سروری که میزبان منابع محافظت شده است. در صورت موفقیت آمیز بودن احراز هویت، توکن دسترسی را تأیید می کند و به منابع دسترسی می دهد.

کاربر، از طریق مشتری، یک رمز دسترسی از سرور مجوز درخواست می کند. اگر احراز هویت موفقیت آمیز باشد، مشتری از این نشانه برای دسترسی به API های محافظت شده توسط سرور منبع استفاده می کند.

در این پست تنها بر روی پیاده سازی سرور منبع تمرکز می کنیم.

نحوه راه اندازی اپلیکیشن Spring Boot

برای تنظیم برنامه خود، به Spring Initializr بروید.

تصویر-44
Spring Initializr

Gradle یا Maven را برای پروژه، نسخه Spring Boot و نام پروژه انتخاب کنید. وابستگی های زیر را اضافه کنید: Spring-boot-Starter-Web و oauth2-resource-server .

برای دانلود اپلیکیشن Spring Boot بر روی Generate کلیک کنید و پس از دانلود، فایل فشرده را استخراج کنید. اکنون باید یک برنامه Spring Boot در حال اجرا با وابستگی ها به طور کامل بارگذاری شده داشته باشید. IntelliJ (یا هر IDE مورد نظر خود را) باز کنید و این پروژه را برای شروع کار انتخاب کنید.

کد کامل این آموزش را می توانید در GitHub پیدا کنید.

پیکربندی امنیت وب

ابتدا application.properties باز کرده و ویژگی زیر را اضافه کنید:

 spring.security.oauth2.resourceserver.jwt.issuer-uri: ${JWT_ISSUER_URI}

می توانید صادرکننده-uri را در پیکربندی open-id سرویس OAuth2 که استفاده می کنید بیابید. به عنوان مثال، پیکربندی Google OAuth2 را تحلیل کنید.

بعد، اجازه دهید Spring Security را پیکربندی کنیم.

برای پیاده سازی سرور منبع، باید Spring Security را به عنوان یکی از وابستگی های خود داشته باشید. در اینجا، ما نیازی به اضافه کردن جداگانه آن نداریم زیرا oauth2-resource-server از Spring Security استفاده می کند.

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

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

از آنجایی که ما احراز هویت مبتنی بر نام کاربری و رمز عبور نمی خواهیم، ​​باید پیکربندی خودکار را غیرفعال کنیم. به کلاس اصلی بروید و استثنای زیر را اضافه کنید:

 @SpringBootApplication(exclude = { SecurityAutoConfiguration.class}) public class Oauth2ResourceServerTutorialApplication { public static void main(String[] args) { SpringApplication.run(Oauth2ResourceServerTutorialApplication.class, args); } }

اگر اکنون برنامه را اجرا کنید، خطا می دهد.

تصویر-45
خطا بدون پیکربندی

اکنون پیکربندی خود را اضافه می کنیم. یک SecurityConfig کلاس Java جدید با حاشیه نویسی های زیر ایجاد کنید:

 @Configuration @EnableWebSecurity public class SecurityConfig { // Beans here }

@Configuration نشان می دهد که این یک کلاس پیکربندی است که شامل چندین متد Bean است که مسئول ایجاد bean هستند. لوبیاها به سادگی اشیایی هستند که بلوک های سازنده برنامه Spring Boot را تشکیل می دهند. @EnableWebSecurity به Spring Boot او میگوید امنیت وب را با تنظیمات شما فعال کند.

روشی ایجاد کنید که یک Bean از نوع SecurityFilterChain را برمی گرداند. Bean زنجیره ای فیلتر امنیتی درخواست های دریافتی را رهگیری می کند و فیلترهای سفارشی را برای آنها اعمال می کند. اینجاست که می‌توانید انواع مختلف مجوز را برای درخواست‌های مختلف اعمال کنید.

 @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authz) -> authz .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); return http.build(); }

بیایید بخش های کلیدی این کد را درک کنیم:

متد filterChain() یک شی HttpSecurity را به عنوان آرگومان می گیرد. این کلاس از Spring Security به شما اجازه می دهد تا درخواست ها را پیکربندی کنید.

متد authorizeHttpRequests() یک شی را می گیرد که ما آن را به عنوان یک عبارت lambda نشان داده ایم.

ما از متد requestMatchers() برای مطابقت با مسیری استفاده کرده‌ایم که بدون احراز هویت قابل دسترسی است. در مورد ما، هر مسیری که از /public شروع شود برای همه قابل دسترسی خواهد بود. درخواست ها به هر مسیر دیگری نیاز به احراز هویت دارند.

روش oauth2ResourceServer() برنامه ما را به عنوان یک سرور منبع OAuth2 تنظیم می کند. در اینجا، ما مشخص می کنیم که احراز هویت JWT با سفارشی سازهای پیش فرض استفاده خواهد شد.

در نهایت، http.build() شی HttpSecurity را می سازد و آن را برمی گرداند.

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

از اسناد سرور منبع JWT دیدن کنید تا راه‌های مختلفی را برای شخصی‌سازی امنیت وب درک کنید.

API ها را در کلاس Controller بنویسید

بیایید دو API ساده بنویسیم. یک کلاس MainController ایجاد کنید که این API ها را در معرض دید قرار دهد:

 @RestController public class MainController { @GetMapping("/public") public String homePage() { return "Hello from Spring boot app"; } @GetMapping("/private") public String privateRoute() { return "Private Route"; } }

@RestController نشان می‌دهد که این کلاس به درخواست‌های HTTP رسیدگی می‌کند و داده‌ها را معمولاً در قالب JSON به مشتری برمی‌گرداند. ما یک API عمومی و خصوصی نوشته ایم.

فایل را ذخیره کنید و برنامه را اجرا کنید.

تست API ها

بیایید APIهای بالا را با استفاده از Postman، بدون هدر مجوز آزمایش کنیم.

تصویر-9
/مسیر عمومی
تصویر-10
/مسیر خصوصی

در دو فراخوانی API بالا، مسیر /public پاسخی را نشان داد، در حالی که مسیر /private یک خطا با وضعیت 401 Unauthorized نشان داد.

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

بیایید یک سرصفحه مجوز را در درخواست به نقطه پایانی /private اضافه کنیم.

تصویر-11
/ درخواست مسیر خصوصی با نشانه دسترسی

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

ما قرار نیست ببینیم که چگونه یک نشانه دسترسی به دست آوریم، زیرا ما فقط بر روی سرور منبع تمرکز می کنیم. مشتری OAuth2 مسئول به دست آوردن رمز دسترسی است. در پست آینده به آن خواهم پرداخت.

نحوه دریافت اطلاعات کاربر از توکن Access

هنگامی که درخواستی را برای یک مسیر خصوصی ارسال می کنید، فیلتر امنیتی این درخواست را رهگیری می کند و به دنبال یک توکن حامل می گردد. اگر توکن وجود داشته باشد، توکن را رمزگشایی می کند و اطلاعات احراز هویت را از توکن استخراج می کند. می توانید کل این فرآیند را با جزئیات از اسناد سرور منبع OAuth2 درک کنید.

اگر توکن معتبر باشد و احراز هویت موفقیت آمیز باشد، داده های احراز هویت در کلاس SecurityContextHolder تنظیم می شوند. SecurityContextHolder حاوی جزئیات کاربر احراز هویت شده است. از این کلاس برای استخراج اطلاعات کاربر مانند نام، ایمیل و ... استفاده می کنیم.

بیایید ببینیم چگونه می توانیم این جزئیات کاربر را بدست آوریم. ابتدا یک شیء Authentication از SecurityContextHolder دریافت می کنیم:

 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

سپس، از getPrincipal() استفاده می کنیم که یک شی را برمی گرداند:

 Object principal = authentication.getPrincipal();

از آنجایی که ما از JWT Authentication استفاده می کنیم، شی فوق را می توان در یک شی از نوع Jwt تایپ کرد. شی شامل فیلدهای زیر است:

 { "tokenValue": token_value, "issuedAt": "", "expiresAt": "", "headers": {...}, "claims": { "name": full_name, "email": user_email, "given_name": first_name, "family_name": last_name, "picture": picture_link, ...other fields }, "subject": "", "id": null, "issuer": issuer_link, "audience": [...], "notBefore": null }

در اینجا، می توانیم داده های کاربر را از قسمت claims دریافت کنیم:

 Map<String, Object> claims = ((Jwt) principal).getClaims();

با استفاده از نقشه فوق می توانیم اطلاعات کاربر را با استفاده از مقدار کلید مربوطه بدست آوریم. بیایید این منطق را در یک کلاس جداگانه CurrentAuthContext بنویسیم:

 public class CurrentAuthContext { private static Map<String, Object> extractClaim() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Object principal = authentication.getPrincipal(); Map<String, Object> claims = ((Jwt) principal).getClaims(); return claims; } public static String getUserEmail() { return (String) extractClaim().get("email"); } }

می توانید روش های بیشتری را برای دریافت جزئیات مورد نیاز خود اضافه کنید. برای دریافت ایمیل کاربر در هر نقطه از برنامه، فقط با CurrentAuthContext.getUserEmail() یا هر روش دیگری که مقدار مورد نیاز شما را برمی گرداند تماس بگیرید.

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

نتیجه

OAuth2 یک چارچوب قوی برای ایمن سازی API های شما و در عین حال دسترسی به کاربران مجاز ارائه می دهد. در این پست با درک OAuth2 و اجزای آن شروع کردیم.

Spring Security یک بخش اساسی از Spring OAuth2 Resource Server است. ما یاد گرفتیم که چگونه پیکربندی های امنیتی را طبق نیاز خود پیاده سازی کنیم. سپس، APIهای عمومی و خصوصی را تعریف کردیم و آنها را با و بدون توکن دسترسی آزمایش کردیم.

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

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

اگر نمی توانید مطالب را درک کنید یا توضیح را رضایت بخش نمی دانید، با من تماس بگیرید. ایده های جدید همیشه قدردانی می شوند! با خیال راحت با من در توییتر ارتباط برقرار کنید. تا اون موقع خداحافظ!!

خبرکاو

ارسال نظر




تبليغات ايهنا تبليغات ايهنا

تمامی حقوق مادی و معنوی این سایت متعلق به خبرکاو است و استفاده از مطالب با ذکر منبع بلامانع است