OAuth 2 login

All lectures for UZ purposes
Daraja, Dars
Mavjud

Spring Boot 2.x da misol

Spring Boot 2.x OAuth 2.0 orqali tizimga kirish uchun avtomatik konfiguratsiyani to'liq foydalanish imkoniyatini beradi.

Bu bo'limda Google yordamida tizimga kirishning kod misoli qanday sozlash haqida ma'lumot beradi va quyidagi mavzular ko'rib chiqiladi:

  • Boshlang'ich sozlash

  • Yo'naltirish URI'larini sozlash

  • application.yml faylini sozlash

  • <Ilova yuklanishi

Boshlang'ich sozlash

Google API Console'da OAuth 2.0 ma'lumotlarini olish uchun loyihani sozlash zarur.

OpenID Connect sahifasidagi "OAuth 2.0 sozlash" bo'limidan boshlab ko'rsatmalarga amal qiling.

"OAuth 2.0 ma'lumotlarini olish" ko'rsatmalarini bajarganingizdan so'ng, mijoz identifikatori va mijoz sirlari mavjud bo'lgan yangi OAuth mijoz paydo bo'ladi.

Yo'naltirish URI'larini sozlash

Yo'naltirish URI ilova ichidagi yo'l bo'lib, Google'da autentifikatsiyadan o'tgandan so'ng foydalanuvchi agenti OAuth mijoziga (oldingi bosqichda yaratilgan) kirish sahifasi orqali yo'naltiriladi.

"Yo'naltirish URI'larini o'rnatish" bo'limida siz yo'naltirilgan URI'lar uchun ruxsat berilganlar maydonida localhost:8080/login/oauth2/code/google bo'lishini ta'minlang.

Yo'naltirish URI uchun odatiy shablon – {baseUrl}/login/oauth2/code/{registrationId}. RegistrationId – ClientRegistration uchun noyob identifikator.
Agar OAuth mijoz proxing server orqali ishlasa, ilovani to'g'ri sozlanganligini tekshirish uchun proxing server konfiguratsiyasini tekshirish tavsiya etiladi. Shuningdek, redirect-uri uchun qo'llab-quvvatlanadigan URI shablon o'zgaruvchilar bilan tanishing.

Application.yml faylini sozlash

Endi Google orqali yangi OAuth mijoz olindi, ilovani autentifikatsiya oqimi uchun OAuth mijozdan foydalanishga sozlash kerak. Buning uchun:

  1. application.yml ga o'ting va quyidagi konfiguratsiyani o'rnating:

    spring:
      security:
        oauth2:
          client:
            registration:	
              google:	
                client-id: google-client-id
                client-secret: google-client-secret
    OAuth mijoz xususiyatlari
    1. spring.security.oauth2.client.registration – bu OAuth mijoz xususiyatlari uchun asosiy prefiks.
    2. Asosiy xususiyat prefiksidan keyin ClientRegistration uchun identifikator, masalan google, keladi.
  2. client-id va client-secret xususiyatlaridagi qiymatlarni oldinroq yaratilgan OAuth 2.0 ma'lumotlariga almashtiring.

Ilovani yuklash

Spring Boot 2.x misolini ishga tushiring va localhost:8080 ga o'ting. Keyin, Google uchun havola mavjud bo'lgan avtomatik yaratilgan standart tizimga kirish sahifasiga yo'naltirilasiz.

Google havolasini bosing, shundan so'ng siz Google'da autentifikatsiya qilinasiz.

Google hisob qaydnomangiz ma'lumotlari bilan autentifikatsiya qilingandan so'ng, keyingi sahifada Kirish shartlari ekrani paydo bo'ladi. Kirish shartlarida sizga oldin yaratilgan OAuth mijoziga kirishga ruxsat berish yoki rad etish taklif etiladi. Mijozga elektron pochtangiz va asosiy profil ma'lumotlariga kirishga ruxsat berish uchun "Ruxsat berish" tugmasini bosing.

Bu bosqichda OAuth mijoz UserInfo manzili orqali elektron pochtangiz va profil asosiy ma'lumotlarini oladi va autentifikatsiyalangan sessiyani o'rnatadi.

Spring Boot 2.x da xususiyatlarini xaritalash

Quyidagi jadvalda Spring Boot 2.x OAuth mijoz xususiyatlarini ClientRegistration xususiyatlariga mosligi ifodalangan.

Spring Boot 2.x ClientRegistration

spring.security.oauth2.client.registration.[registrationId]

registrationId

spring.security.oauth2.client.registration.[registrationId].client-id

clientId

spring.security.oauth2.client.registration.[registrationId].client-secret

clientSecret

spring.security.oauth2.client.registration.[registrationId].client-authentication-method

clientAuthenticationMethod

spring.security.oauth2.client.registration.[registrationId].authorization-grant-type

authorizationGrantType

spring.security.oauth2.client.registration.[registrationId].redirect-uri

redirectUri

spring.security.oauth2.client.registration.[registrationId].scope

scopes

spring.security.oauth2.client.registration.[registrationId].client-name

clientName

spring.security.oauth2.client.provider.[providerId].authorization-uri

providerDetails.authorizationUri

spring.security.oauth2.client.provider.[providerId].token-uri

providerDetails.tokenUri

spring.security.oauth2.client.provider.[providerId].jwk-set-uri

providerDetails.jwkSetUri

spring.security.oauth2.client.provider.[providerId].issuer-uri

providerDetails.issuerUri

spring.security.oauth2.client.provider.[providerId].user-info-uri

providerDetails.userInfoEndpoint.uri

spring.security.oauth2.client.provider.[providerId].user-info-authentication-method

providerDetails.userInfoEndpoint.authenticationMethod

spring.security.oauth2.client.provider.[providerId].user-name-attribute

providerDetails.userInfoEndpoint.userNameAttributeName

ClientRegistration dastlab OpenID Connect konfiguratsiya manzili yoki authorization server metadata manzilidan foydalanib konfiguratsiyalanishi mumkin.

CommonOAuth2Provider

CommonOAuth2Provider bir necha taniqli provayderlar uchun mijozning standart xususiyatlarini oldindan belgilaydi: Google, GitHub, Facebook va Okta.

Masalan, authorization-uri, token-uri va user-info-uri biror provayder uchun kamdan-kam o'zgaradi. Shuning uchun kamroq konfiguratsiya qilish kerak bo'lgan qiymatlarni oldindan belgilash mantiqan to'g'ri.

Ilgari ko'rsatib o'tilganidek, Google mijozini sozlashda zarur bo'lgan faqat client-id va client-secret xususiyatlaridir.

Quyidagi ro'yxatda misol keltirilgan:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: google-client-id
            client-secret: google-client-secret
Bu yerda mijozning standart xususiyatlarini avtomatik aniqlash muammosiz ishlaydi, chunki registrationId ( google) CommonOAuth2Provider ichidagi GOOGLE enumga (ro'yxatga olishda aniqlanmagan) mos keladi.

Boshqa registrationIdni, masalan, google-loginni belgilash kerak bo'lsa, baribir provider xususiyatini sozlash orqali mijozning standart xususiyatlarini avtomatik aniqlashdan foydalanish mumkin.

Quyidagi ro'yxatda misol keltirilgan:

spring:
  security:
    oauth2:
      client:
        registration:
          google-login:	
            provider: google	
            client-id: google-client-id
            client-secret: google-client-secret
  1. Uchun registrationId google-login qiymati o'rnatilgan.
  2. provider xususiyati google qiymati bilan o'rnatilgan, bu esa CommonOAuth2Provider.GOOGLE.getBuilder() da o'rnatilgan mijozning standart xususiyatlarini avtomatik aniqlashga imkon beradi.

Kastom provayder xususiyatlarini sozlash

Ba'zi OAuth 2.0 provayderlari ko'p ijarali rejimda ishlashni qo'llab-quvvatlaydi, bu esa har bir ijara yoki subdomen uchun turli protokol manzillarini yaratishga olib keladi.

Masalan, Okta'da ro'yxatdan o'tkazilgan OAuth mijoziga muayyan subdomen biriktiriladi va o'ziga xos protokol manzillariga ega.

Bunday holatlar uchun Spring Boot 2.x quyidagi asosiy xususiyatni provayder xususiyatlarini kastomlashtirish uchun taqdim etadi: spring.security.oauth2.client.provider.[providerId].

Quyidagi ro'yxatda misol keltirilgan:

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-secret: okta-client-secret
        provider:
          okta:	
            authorization-uri: https://your-subdomain.oktapreview.com/oauth2/v1/authorize
            token-uri: https://your-subdomain.oktapreview.com/oauth2/v1/token
            user-info-uri: https://your-subdomain.oktapreview.com/oauth2/v1/userinfo
            user-name-attribute: sub
            jwk-set-uri: https://your-subdomain.oktapreview.com/oauth2/v1/keys
  1. Asosiy xususiyat (spring.security.oauth2.client.provider.okta) protokol manzilini kastomlashtirish imkonini beradi.

Spring Boot 2.x avtomatik konfiguratsiyasini hisobdan chiqarish

Spring Boot 2.x ning OAuth mijozini qo'llab-quvvatlash uchun avtomatik konfiguratsiya klassi – OAuth2ClientAutoConfiguration.

U quyidagi vazifalarni bajaradi:

  • O'zgartirilgan OAuth mijoz xususiyatlaridan ClientRegistrationRepository nusxasini moslama sifatida ro'yxatdan o'tkazadi.

  • SecurityFilterChain moslamasini ro'yxatdan o'tkazadi va httpSecurity.oauth2Login() orqali OAuth 2.0 avtentifikatsiyasini faollashtiradi.

Agar avtomatik konfiguratsiyani o'ziga xos ehtiyojlar uchun hisobdan chiqarish kerak bo'lsa, quyidagi usullar orqali amalga oshirish mumkin:

  • ClientRegistrationRepository uchun @Bean ro'yxatdan o'tkazish

  • SecurityFilterChain uchun @Bean ro'yxatdan o'tkazish

  • To'liq avtomatik konfiguratsiyani hisobdan chiqarish

ClientRegistrationRepository uchun @Bean ro'yxatdan o'tkazish

Quyidagi misolda, ClientRegistrationRepository uchun @Bean ro'yxatdan o'tkazish ko'rsatilgan:

Java
@Configuration
public class OAuth2LoginConfig {
	@Bean
	public ClientRegistrationRepository clientRegistrationRepository() {
		return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
	}
	private ClientRegistration googleClientRegistration() {
		return ClientRegistration.withRegistrationId("google")
			.clientId("google-client-id")
			.clientSecret("google-client-secret")
			.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
			.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
			.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
			.scope("openid", "profile", "email", "address", "phone")
			.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
			.tokenUri("https://www.googleapis.com/oauth2/v4/token")
			.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
			.userNameAttributeName(IdTokenClaimNames.SUB)
			.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
			.clientName("Google")
			.build();
	}
}
Kotlin
@Configuration
class OAuth2LoginConfig {
    @Bean
    fun clientRegistrationRepository(): ClientRegistrationRepository {
        return InMemoryClientRegistrationRepository(googleClientRegistration())
    }
    private fun googleClientRegistration(): ClientRegistration {
        return ClientRegistration.withRegistrationId("google")
                .clientId("google-client-id")
                .clientSecret("google-client-secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
                .scope("openid", "profile", "email", "address", "phone")
                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
                .tokenUri("https://www.googleapis.com/oauth2/v4/token")
                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
                .userNameAttributeName(IdTokenClaimNames.SUB)
                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
                .clientName("Google")
                .build()
    }
}

SecurityFilterChain uchun @Bean ro'yxatdan o'tkazish

Quyidagi misolda SecurityFilterChain uchun @Bean ro'yxatdan o'tkazish va httpSecurity.oauth2Login() orqali OAuth 2.0 avtentifikatsiyasini faollashtirish ko'rsatilgan:

OAuth2 tizimga kirish konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorize -> authorize
				.anyRequest().authenticated()
			)
			.oauth2Login(withDefaults());
		return http.build();
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeRequests {
                authorize(anyRequest, authenticated)
            }
            oauth2Login { }
        }
        return http.build()
    }
}

To'liq avtomatik konfiguratsiyani hisobdan chiqarish

Quyidagi misolda ClientRegistrationRepository uchun @Bean va SecurityFilterChain uchun @Bean ro'yxatdan o'tkazilishini to'liq avtomatik konfiguratsiyani hisobdan chiqarish ko'rsatilgan.

Avtomatik konfiguratsiyani hisobdan chiqarish
Java
@Configuration
public class OAuth2LoginConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorize -> authorize
				.anyRequest().authenticated()
			)
			.oauth2Login(withDefaults());
		return http.build();
	}
	@Bean
	public ClientRegistrationRepository clientRegistrationRepository() {
		return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
	}
	private ClientRegistration googleClientRegistration() {
		return ClientRegistration.withRegistrationId("google")
			.clientId("google-client-id")
			.clientSecret("google-client-secret")
			.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
			.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
			.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
			.scope("openid", "profile", "email", "address", "phone")
			.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
			.tokenUri("https://www.googleapis.com/oauth2/v4/token")
			.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
			.userNameAttributeName(IdTokenClaimNames.SUB)
			.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
			.clientName("Google")
			.build();
	}
}
Kotlin
@Configuration
class OAuth2LoginConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeRequests {
                authorize(anyRequest, authenticated)
            }
            oauth2Login { }
        }
        return http.build()
    }
    @Bean
    fun clientRegistrationRepository(): ClientRegistrationRepository {
        return InMemoryClientRegistrationRepository(googleClientRegistration())
    }
    private fun googleClientRegistration(): ClientRegistration {
        return ClientRegistration.withRegistrationId("google")
                .clientId("google-client-id")
                .clientSecret("google-client-secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
                .scope("openid", "profile", "email", "address", "phone")
                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
                .tokenUri("https://www.googleapis.com/oauth2/v4/token")
                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
                .userNameAttributeName(IdTokenClaimNames.SUB)
                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
                .clientName("Google")
                .build()
    }
}

Spring Boot 2.x bo'lmagan holda Java asosidagi konfiguratsiya

Agar Spring Boot 2.x dan foydalanish imkoni bo'lmasa, lekin CommonOAuth2Provider ichidagi oldindan belgilangan provayderlardan birini (masalan, Google) sozlash kerak bo'lsa, quyidagi konfiguratsiyani qo'llang:

OAuth2 tizimga kirish konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorize -> authorize
				.anyRequest().authenticated()
			)
			.oauth2Login(withDefaults());
		return http.build();
	}
	@Bean
	public ClientRegistrationRepository clientRegistrationRepository() {
		return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
	}
	@Bean
	public OAuth2AuthorizedClientService authorizedClientService(
			ClientRegistrationRepository clientRegistrationRepository) {
		return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
	}
	@Bean
	public OAuth2AuthorizedClientRepository authorizedClientRepository(
			OAuth2AuthorizedClientService authorizedClientService) {
		return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
	}
	private ClientRegistration googleClientRegistration() {
		return CommonOAuth2Provider.GOOGLE.getBuilder("google")
			.clientId("google-client-id")
			.clientSecret("google-client-secret")
			.build();
	}
}
Kotlin
@EnableWebSecurity
open class OAuth2LoginConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeRequests {
                authorize(anyRequest, authenticated)
            }
            oauth2Login { }
        }
        return http.build()
    }
    @Bean
    open fun clientRegistrationRepository(): ClientRegistrationRepository {
        return InMemoryClientRegistrationRepository(googleClientRegistration())
    }
    @Bean
    open fun authorizedClientService(
        clientRegistrationRepository: ClientRegistrationRepository?
    ): OAuth2AuthorizedClientService {
        return InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository)
    }
    @Bean
    open fun authorizedClientRepository(
        authorizedClientService: OAuth2AuthorizedClientService?
    ): OAuth2AuthorizedClientRepository {
        return AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService)
    }
    private fun googleClientRegistration(): ClientRegistration {
        return CommonOAuth2Provider.GOOGLE.getBuilder("google")
            .clientId("google-client-id")
            .clientSecret("google-client-secret")
            .build()
    }
}
Xml
<http auto-config="true">
	<intercept-url pattern="/**" access="authenticated"/>
	<oauth2-login authorized-client-repository-ref="authorizedClientRepository"/>
</http>
<client-registrations>
	<client-registration registration-id="google"
						 client-id="google-client-id"
						 client-secret="google-client-secret"
						 provider-id="google"/>
</client-registrations>
<b:bean id="authorizedClientService"
		class="org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService"
		autowire="constructor"/>
<b:bean id="authorizedClientRepository"
		class="org.springframework.security.oauth2.client.web.AuthenticatedPrincipalOAuth2AuthorizedClientRepository">
	<b:constructor-arg ref="authorizedClientService"/>
</b:bean>
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION