JavaRush /Kurslar /All lectures for UZ purposes /Kengaytirilgan konfiguratsiya

Kengaytirilgan konfiguratsiya

All lectures for UZ purposes
Daraja, Dars
Mavjud

HttpSecurity.oauth2Login() OAuth 2.0 da avtorizatsiyani sozlash uchun bir qator konfiguratsiya imkoniyatlarini taqdim etadi. Asosiy konfiguratsiya imkoniyatlari protokolning nuqtalariga mos keladigan guruhlarga bo'linadi.

Masalan, oauth2Login().authorizationEndpoint() avtorizatsiya nuqtasini sozlash imkonini beradi, holbuki oauth2Login().tokenEndpoint() tokenlar nuqtasini sozlash imkonini beradi.

Quyidagi kodda misol ko'rsatilgan:

OAuth2 da tizimga kirish uchun kengaytirilgan konfiguratsiya
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .authorizationEndpoint(authorization -> authorization
			            ...
			    )
			    .redirectionEndpoint(redirection -> redirection
			            ...
			    )
			    .tokenEndpoint(token -> token
			            ...
			    )
			    .userInfoEndpoint(userInfo -> userInfo
			            ...
			    )
			);
		return http.build();
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                authorizationEndpoint {
                    ...
                }
                redirectionEndpoint {
                    ...
                }
                tokenEndpoint {
                    ...
                }
                userInfoEndpoint {
                    ...
                }
            }
        }
        return http.build()
    }
}

DSL asosidagi oauth2Login() yaratishning asosiy maqsadi spetsifikatsiyalar bilan yaqindan muvofiqligini ta'minlash edi.

OAuth 2.0 avtorizatsiya freymvurki protokol nuqtalarini quyidagicha belgilaydi:

Avtorizatsiya jarayonida avtorizatsiya serverining ikkita nuqtasi ishlatiladi (HTTP resurslari):

  • Avtorizatsiya nuqtasi: resurs egasidan avtorizatsiya olish uchun foydalanuvchi agentini qayta yo'naltirish orqali mijoz tomonidan ishlatiladi.

  • Tokenlar nuqtasi: odatda mijozni autentifikatsiyalash paytida kirish ruxsatnomasini almashish uchun mijoz tomonidan ishlatiladi.

Shuningdek, bitta mijoz nuqtasi mavjud:

  • Pereadresatsiya nuqtasi: avtorizatsiya serveri tomonidan avtorizatsiya ma'lumotlarini o'z ichiga olgan javoblarni foydalanuvchi agenti orqali mijozga qaytarish uchun ishlatiladi.

OpenID Connect Core 1.0 spetsifikatsiyasi UserInfo nuqtasini quyidagicha belgilaydi:

UserInfo nuqtasi autentifikatsiya qilingan oxirgi foydalanuvchi ma'lumotlarini qaytaradigan OAuth 2.0 tomonidan himoyalangan resursdir. Oxirgi foydalanuvchi so'ralgan ma'lumotlarni olish uchun mijoz OpenID Connect autentifikatsiyasi orqali olingan kirish tokenidan foydalangan holda UserInfo nuqtasiga so'rov yuboradi. Bu da'vo qilingan qiymatlar odatda JSON ob'ekti shaklida taqdim etiladi, bu erda "nom-qiymat" juftliklar to'plamini o'z ichiga oladi.

Quyidagi kodda DSL asosidagi oauth2Login() uchun mavjud barcha konfiguratsiya parametrlarini ko'rsatadi:

OAuth2 avtorizatsiya konfiguratsiya parametrlari
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .clientRegistrationRepository(this.clientRegistrationRepository())
			    .authorizedClientRepository(this.authorizedClientRepository())
			    .authorizedClientService(this.authorizedClientService())
			    .loginPage("/login")
			    .authorizationEndpoint(authorization -> authorization
			        .baseUri(this.authorizationRequestBaseUri())
			        .authorizationRequestRepository(this.authorizationRequestRepository())
			        .authorizationRequestResolver(this.authorizationRequestResolver())
			    )
			    .redirectionEndpoint(redirection -> redirection
			        .baseUri(this.authorizationResponseBaseUri())
			    )
			    .tokenEndpoint(token -> token
			        .accessTokenResponseClient(this.accessTokenResponseClient())
			    )
			    .userInfoEndpoint(userInfo -> userInfo
			        .userAuthoritiesMapper(this.userAuthoritiesMapper())
			        .userService(this.oauth2UserService())
			        .oidcUserService(this.oidcUserService())
			    )
			);
		return http.build();
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                clientRegistrationRepository = clientRegistrationRepository()
                authorizedClientRepository = authorizedClientRepository()
                authorizedClientService = authorizedClientService()
                loginPage = "/login"
                authorizationEndpoint {
                    baseUri = authorizationRequestBaseUri()
                    authorizationRequestRepository = authorizationRequestRepository()
                    authorizationRequestResolver = authorizationRequestResolver()
                }
                redirectionEndpoint {
                    baseUri = authorizationResponseBaseUri()
                }
                tokenEndpoint {
                    accessTokenResponseClient = accessTokenResponseClient()
                }
                userInfoEndpoint {
                    userAuthoritiesMapper = userAuthoritiesMapper()
                    userService = oauth2UserService()
                    oidcUserService = oidcUserService()
                }
            }
        }
        return http.build()
    }
}

DSL asosidagi oauth2Login() qo'shimcha ravishda XML konfiguratsiyasini ham qo'llab-quvvatlaydi.

Quyidagi kodda <Security Namespace> da mavjud bo'lgan barcha konfiguratsiya parametrlari ko'rsatilgan:

XML konfiguratsiyasi OAuth2 Login parametrlari
<http>
	<oauth2-login client-registration-repository-ref="clientRegistrationRepository"
				  authorized-client-repository-ref="authorizedClientRepository"
				  authorized-client-service-ref="authorizedClientService"
				  authorization-request-repository-ref="authorizationRequestRepository"
				  authorization-request-resolver-ref="authorizationRequestResolver"
				  access-token-response-client-ref="accessTokenResponseClient"
				  user-authorities-mapper-ref="userAuthoritiesMapper"
				  user-service-ref="oauth2UserService"
				  oidc-user-service-ref="oidcUserService"
				  login-processing-url="/login/oauth2/code/*"
				  login-page="/login"
				  authentication-success-handler-ref="authenticationSuccessHandler"
				  authentication-failure-handler-ref="authenticationFailureHandler"
				  jwt-decoder-factory-ref="jwtDecoderFactory"/>
</http>

Quyidagi bo'limlarda mavjud bo'lgan har bir konfiguratsiya variantiga batafsilroq izoh berilgan:

  • OAuth 2.0 kirish sahifasi

  • Pereadresatsiya nuqtasi

  • UserInfo nuqtasi

  • ID token signaturasini tasdiqlash

  • OpenID Connect 1.0 tizimdan chiqish

OAuth 2.0 kirish sahifasi

OAuth 2.0 kirish sahifasi odatda DefaultLoginPageGeneratingFilter orqali avtomatik ravishda hosil qilinadi. Standart kirish sahifasi har bir moslashtirilgan OAuth mijozini o'z ClientRegistration.clientName bilan bog'laydi, bu orqali avtorizatsiya so'rovini (yoki OAuth 2.0 kirish) boshlash mumkin.

Agar DefaultLoginPageGeneratingFilter moslashtirilgan OAuth mijozlar uchun havolalarni ko'rsatsa, ro'yxatdan o'tgan ClientRegistrationRepository shuningdek, Iterable<ClientRegistration> ni amalga oshirishi kerak. Qo'shimcha ma'lumot uchun InMemoryClientRegistrationRepository ga qarang.

Har bir OAuth mijoz uchun standart havola quyidagi ko'rinishda bo'ladi:

OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/{registrationId}"

Quyidagi qator misol keltirilgan:

<a href="/oauth2/authorization/google">Google</a>

Standart kirish sahifasini o'zgartirish uchun oauth2Login().loginPage() ni va (ixtiyoriy ravishda) oauth2Login().authorizationEndpoint().baseUri() ni sozlang.

Quyidagi listda misol keltirilgan:

OAuth2 kirish sahifasi konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .loginPage("/login/oauth2")
			    ...
			    .authorizationEndpoint(authorization -> authorization
			        .baseUri("/login/oauth2/authorization")
			        ...
			    )
			);
		return http.build();
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                loginPage = "/login/oauth2"
                authorizationEndpoint {
                    baseUri = "/login/oauth2/authorization"
                }
            }
        }
        return http.build()
    }
}
Xml
<http>
	<oauth2-login login-page="/login/oauth2"
				  ...
    />
</http>
Siz @Controller annotatsiyasida parametr @RequestMapping("/login/oauth2") ni ko'rsatishingiz kerak bo'ladi, u sizning moslashtirilgan kirish sahifangizni vizuallashtiradi.

Ilgari aytilganidek, oauth2Login().authorizationEndpoint().baseUri() ni konfiguratsiyaga qo'shish ixtiyoriy. Ammo agar o'zgartirishni amalga oshirmoqchi bo'lsangiz, har bir OAuth mijoziga havola authorizationEndpoint().baseUri() ga mos kelayotganiga ishonch hosil qiling.

Quyidagi qator misol keltirilgan:

<a href="/login/oauth2/authorization/google">Google</a>

Pereadresatsiya nuqtasi

Pereadresatsiya nuqtasi foydalanuvchi agenti orqali mijozga javobni (autentifikatsiya kimligini o'z ichiga olgan) qaytarish uchun avtorizatsiya serveri tomonidan ishlatiladi.

OAuth 2.0 tizimga kirish kirish kodini olishni o'z ichiga oladi. Shuning uchun avtorizatsiya kimligi avtorizatsiya kodi hisoblanadi.

Default baseUri uchun avtorizatsiya javobi (pereadresatsiya nuqtasi) /login/oauth2/code/* bo'lib, u OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI da aniqlangan.

Agar avtorizatsiya javobining baseUri nuqtasini sozlash kerak bo'lsa, uni quyidagi misolda ko'rsatilganidek sozlang:

Pereadresatsiya nuqtasi konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
    @Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .redirectionEndpoint(redirection -> redirection
			        .baseUri("/login/oauth2/callback/*")
			        ...
			    )
			);
		return http.build();
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                redirectionEndpoint {
                    baseUri = "/login/oauth2/callback/*"
                }
            }
        }
        return http.build()
    }
}
Xml
<http>
	<oauth2-login login-processing-url="/login/oauth2/callback/*"
				  ...
    />
</http>

Siz shuningdek, ClientRegistration.redirectUri ni moslashtirilgan avtorizatsiya javobining baseUri ga mos kelayotganligiga ishonch hosil qilishingiz kerak.

Quyidagi listda misol keltirilgan:

Java
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
	.clientId("google-client-id")
	.clientSecret("google-client-secret")
	.redirectUri("{baseUrl}/login/oauth2/callback/{registrationId}")
	.build();
Kotlin
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
    .clientId("google-client-id")
    .clientSecret("google-client-secret")
    .redirectUri("{baseUrl}/login/oauth2/callback/{registrationId}")
    .build()

UserInfo nuqtasi

UserInfo nuqtasi bir qator konfiguratsiya imkoniyatlarini o'z ichiga oladi, ular quyidagi kichik bo'limlarda bayon etilgan:

  • Foydalanuvchi huquqlarini tasvirlash

  • OAuth 2.0 UserService

  • OpenID Connect 1.0 UserService

Foydalanuvchi huquqlarini tasvirlash

OAuth 2.0 orqali muvaffaqiyatli autentifikatsiyaga ega bo'lgan foydalanuvchining OAuth2User.getAuthorities() (yoki OidcUser.getAuthorities()) yangi GrantedAuthority instance to'plamiga tasvirlanishi mumkin, ular autentifikatsiyani yakunlashda OAuth2AuthenticationToken ga o'tkaziladi.

OAuth2AuthenticationToken.getAuthorities() kirishlar uchun autentifikatsiya qilishda ishlatiladi, masalan, hasRole('USER') yoki hasRole('ADMIN').

Foydalanuvchi huquqlarini tasvirlash uchun bir nechta variant mavjud:

  • GrantedAuthoritiesMapper dan foydalanish

  • OAuth2UserService orqali delegatsiya asosida strategiya

GrantedAuthoritiesMapper dan foydalanish

GrantedAuthoritiesMapper ni amalga oshirishni belgilaymiz va uni quyidagi misolda ko'rsatilganidek sozlaymiz:

Tasvirlangan huquqlar konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
    @Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .userInfoEndpoint(userInfo -> userInfo
			        .userAuthoritiesMapper(this.userAuthoritiesMapper())
			        ...
			    )
			);
		return http.build();
	}
	private GrantedAuthoritiesMapper userAuthoritiesMapper() {
		return (authorities) -> {
			Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
			authorities.forEach(authority -> {
				if (OidcUserAuthority.class.isInstance(authority)) {
					OidcUserAuthority oidcUserAuthority = (OidcUserAuthority)authority;
					OidcIdToken idToken = oidcUserAuthority.getIdToken();
					OidcUserInfo userInfo = oidcUserAuthority.getUserInfo();
					// IdToken va/yo userInfo da topilgan da'vo qilingan qiymatlarni
					// bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
				} else if (OAuth2UserAuthority.class.isInstance(authority)) {
					OAuth2UserAuthority oauth2UserAuthority = (OAuth2UserAuthority)authority;
					Map<String, Object> userAttributes = oauth2UserAuthority.getAttributes();
					// userAttributes da topilgan atributlarni
					// bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
				}
			});
			return mappedAuthorities;
		};
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                userInfoEndpoint {
                    userAuthoritiesMapper = userAuthoritiesMapper()
                }
            }
        }
        return http.build()
    }
    private fun userAuthoritiesMapper(): GrantedAuthoritiesMapper = GrantedAuthoritiesMapper { authorities: Collection<GrantedAuthority> ->
        val mappedAuthorities = emptySet<GrantedAuthority>()
        authorities.forEach { authority ->
            if (authority is OidcUserAuthority) {
                val idToken = authority.idToken
                val userInfo = authority.userInfo
                // IdToken va/yo userInfo da topilgan da'vo qilingan qiymatlarni
                // bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
            } else if (authority is OAuth2UserAuthority) {
                val userAttributes = authority.attributes
                // userAttributes da topilgan atributlarni
                // bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
            }
        }
        mappedAuthorities
    }
}
Xml
<http>
	<oauth2-login user-authorities-mapper-ref="userAuthoritiesMapper"
				  ...
    />
</http>

Bundan tashqari, GrantedAuthoritiesMapper uchun @Bean ni ro'yxatdan o'tkazishingiz mumkin, shunda u avtomatik ravishda konfiguratsiyaga qo'llaniladi, quyidagi misolda ko'rsatilganidek:

Qo'llangan huquqlarni bin orqali tasvirlash konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
		    .oauth2Login(withDefaults());
		return http.build();
	}
	@Bean
	public GrantedAuthoritiesMapper userAuthoritiesMapper() {
		...
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login { }
        }
        return http.build()
    }
    @Bean
    fun userAuthoritiesMapper(): GrantedAuthoritiesMapper {
        ...
    }
}

Delegatsiya asosida strategiya OAuth2UserService orqali

Ushbu strategiya GrantedAuthoritiesMapper dan foydalanishga qaraganda yanada rivojlangan, lekin u ham yanada moslashuvchan, chunki u OAuth2UserRequest va OAuth2User (OAuth 2.0 UserService dan foydalanish orqali) yoki OidcUserRequest va OidcUser (OpenID Connect 1.0 UserService dan foydalanish orqali) ga kirish imkonini beradi.

OAuth2UserRequest (va OidcUserRequest) tegishli OAuth2AccessToken ga kirish imkonini beradi, bu juda foydali, agar "delegate" ob'ekti foydalanuvchi uchun moslashtirilgan vakolatlarni tasvirlamasdan oldin qo'riqlanadigan resursdan ruxsatnoma ma'lumotlarini olish kerak bo'lsa.

Quyidagi misolda OpenID Connect 1.0 UserService dan foydalanib, delegatsiya asosida strategiyani amalga oshirish va sozlash ko'rsatilgan:

OAuth2UserService konfiguratsiyasi
Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .userInfoEndpoint(userInfo -> userInfo
			        .oidcUserService(this.oidcUserService())
			        ...
			    )
			);
		return http.build();
	}
	private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
		final OidcUserService delegate = new OidcUserService();
		return (userRequest) -> {
			// Standart implementatsiyani vakolatlarni yuklash uchun delegatsiya qilamiz
			OidcUser oidcUser = delegate.loadUser(userRequest);
			OAuth2AccessToken accessToken = userRequest.getAccessToken();
			Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
			// TODO
			// 1) Kirish tokenidan foydalanib himoyalangan resursdan vakolatlar ma'lumotlarini olish
			// 2) Vakolatlar ma'lumotlarini bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
			// 3) oidcUser ning nusxasini yarating, lekin mappedAuthorities dan foydalaning
			oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());
			return oidcUser;
		};
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig  {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                userInfoEndpoint {
                    oidcUserService = oidcUserService()
                }
            }
        }
        return http.build()
    }
    @Bean
    fun oidcUserService(): OAuth2UserService<OidcUserRequest, OidcUser> {
        val delegate = OidcUserService()
        return OAuth2UserService { userRequest ->
            // Standart implementatsiyani vakolatlarni yuklash uchun delegatsiya qilamiz
            var oidcUser = delegate.loadUser(userRequest)
            val accessToken = userRequest.accessToken
            val mappedAuthorities = HashSet<GrantedAuthority>()
            // TODO
            // 1) Kirish tokenidan foydalanib himoyalangan resursdan vakolatlar ma'lumotlarini olish
            // 2) Vakolatlar ma'lumotlarini bir yoki bir nechta GrantedAuthority ga tasvirlaymiz va mappedAuthorities ga qo'shamiz
            // 3) oidcUser ning nusxasini yarating, lekin mappedAuthorities dan foydalaning
            oidcUser = DefaultOidcUser(mappedAuthorities, oidcUser.idToken, oidcUser.userInfo)
            oidcUser
        }
    }
}
Xml
<http>
	<oauth2-login oidc-user-service-ref="oidcUserService"
				  ...
    />
</http>

OAuth 2.0 UserService

DefaultOAuth2UserService – OAuth 2.0 standart yetkazib beruvchilarini qo'llab-quvvatlaydigan OAuth2UserService implementatsiyasi.

OAuth2UserService oxirgi foydalanuvchining (resurs egasining) foydalanuvchi atributlarini UserInfo nuqtasidan (avtorizatsiya jarayonida mijozga taqdim etilgan kirish tokenidan foydalanib) oladi va AuthenticatedPrincipal ni OAuth2User shaklida qaytaradi.

DefaultOAuth2UserService foydalanuvchi atributlari uchun UserInfo nuqtasiga so'rov yuborishda RestOperations dan foydalanadi.

Agar UserInfo so'rovini oldindan qayta ishlashni sozlash kerak bo'lsa, DefaultOAuth2UserService.setRequestEntityConverter() ga moslashuvchan Converter<OAuth2UserRequest, RequestEntity<?>> ni o'tkazing. Standart implementatsiya OAuth2UserRequestEntityConverter UserInfo so'rovini taqdim etish uchun RequestEntity ni quradi, bu esa OAuth2AccessToken ni Authorization headeriga qo'yadi.

Aks holda, agar UserInfo javobini post-qayta ishlashni sozlash kerak bo'lsa, DefaultOAuth2UserService.setRestOperations() ni moslashtirilgan RestOperations bilan o'tkazing. Default RestOperations quyidagicha sozlangan:

RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());

OAuth2ErrorResponseErrorHandler – bu ResponseErrorHandler bo'lib, OAuth 2.0 xatolarini (400 Bad Request) qayta ishlay oladi. Bu OAuth2ErrorHttpMessageConverter dan OAuth 2.0 xato parametrlarini OAuth2Error ga aylantirish uchun foydalanadi.

Nima bo'lganda ham, siz DefaultOAuth2UserService ni sozlaysizmi yoki OAuth2UserService ni o'z implementatsiyangizni o'tkazasizmi, quyidagi misolda ko'rsatilganidek uni sozlashingiz kerak bo'ladi:

Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
			    .userInfoEndpoint(userInfo -> userInfo
			        .userService(this.oauth2UserService())
			        ...
			    )
			);
		return http.build();
	}
	private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
		...
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                userInfoEndpoint {
                    userService = oauth2UserService()
                    // ...
                }
            }
        }
        return http.build()
    }
    private fun oauth2UserService(): OAuth2UserService<OAuth2UserRequest, OAuth2User> {
        // ...
    }
}

OpenID Connect 1.0 UserService

OidcUserService – bu OpenID Connect 1.0 uchun OAuth2UserService implementatsiyasi.

OidcUserService UserInfo nuqtasiga so'rov yuborishda DefaultOAuth2UserService dan foydalanadi.

Agar UserInfo so'rovinioldindan qayta ishlashni va/yoki UserInfo javobini qayta ishlashni sozlash kerak bo'lsa, OidcUserService.setOauth2UserService() ga moslashtirilgan DefaultOAuth2UserService ni o'tkazing.

Nima bo'lganda ham, siz OidcUserService ni sozlaysizmi yoki OpenID Connect 1.0 uchun o'z OAuth2UserService implementatsiyangizni o'tkazasizmi, quyidagi misolda ko'rsatilganidek uni sozlashingiz kerak bo'ladi:

Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.oauth2Login(oauth2 -> oauth2
				.userInfoEndpoint(userInfo -> userInfo
				    .oidcUserService(this.oidcUserService())
				    ...
			    )
			);
		return http.build();
	}
	private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
		...
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            oauth2Login {
                userInfoEndpoint {
                    oidcUserService = oidcUserService()
                    // ...
                }
            }
        }
        return http.build()
    }
    private fun oidcUserService(): OAuth2UserService<OidcUserRequest, OidcUser> {
        // ...
    }
}

ID token signaturasini tasdiqlash

OpenID Connect 1.0 autentifikatsiyasi asosida mijoz tomonidan serveridan avtorizatsiya qilingan oxirgi foydalanuvchi tasdiq ma'lumotlarini o'z ichiga olgan ID token mavjud.

ID token JSON veb-tokeni (JWT) shaklida taqdim etiladi va JSON veb-sigatura (JWS) yordamida imzolanadi.

OidcIdTokenDecoderFactory imzo OidcIdToken ni tasdiqlash uchun foydalaniladigan JwtDecoder ni ta'minlaydi. Default algoritmi RS256 bo'lsa-da, u klient uchun belgilangan bo'lsa, o'zgartirilishi mumkin. Bunday holatlarda dekoder klient uchun belgilangan JWS algoritmini qaytarish uchun o'zgartiriladi.

JWS algoritmi dekoderi ClientRegistration ni oladigan va klient uchun kerakli JwsAlgorithm ni qaytaradigan Function hisoblanadi, masalan SignatureAlgorithm.RS256 yoki MacAlgorithm.HS256.

Quyidagi kodda barcha ClientRegistration uchun default MacAlgorithm.HS256 dan foydalanadigan OidcIdTokenDecoderFactory uchun @Bean ni qanday sozlash ko'rsatilgan:

Java
@Bean
public JwtDecoderFactory<ClientRegistration> idTokenDecoderFactory() {
	OidcIdTokenDecoderFactory idTokenDecoderFactory = new OidcIdTokenDecoderFactory();
	idTokenDecoderFactory.setJwsAlgorithmResolver(clientRegistration -> MacAlgorithm.HS256);
	return idTokenDecoderFactory;
}
Kotlin
@Bean
fun idTokenDecoderFactory(): JwtDecoderFactory<ClientRegistration?> {
    val idTokenDecoderFactory = OidcIdTokenDecoderFactory()
    idTokenDecoderFactory.setJwsAlgorithmResolver { MacAlgorithm.HS256 }
    return idTokenDecoderFactory
}
MAC asosidagi algoritmlar uchun, masalan, HS256, HS384 yoki HS512 uchun simmetrik kalit imzoni tasdiqlashda mijozning maxfiy kaliti, client-id ga mos keladigan client-secret sifatida ishlatiladi.
OpenID Connect 1.0 autentifikatsiyasi uchun bir nechta ClientRegistration ni sozlashda, JWS algoritmini tanlaydigan dekoder client's ClientRegistration ni tekshirib, qaysi algoritmni qaytarish kerakligini aniqlashi mumkin.

OpenID Connect 1.0 tizimdan chiqish

OpenID Connect Session Management 1.0 mijoz tomonidan xizmat ko'rsatuvchi tomonidan oxirgi foydalanuvchini tizimdan chiqishni ro'yxatdan o'tkazishni qo'llab-quvvatlash imkoniyatini ta'minlaydi. Mavjud strategiyalar haqida biri – mijoz tomonidan boshqariladigan chiqish (RP-Initiated Logout).

Agar OpenID yetkazib beruvchi sessiya boshqaruvi va aniqlovchi ni qo'llab-quvvatlasa, mijoz end_session_endpoint ni OpenID yetkazib beruvchi aniqlovchi metadata dan URL manzilini olishi mumkin. Bu issuer-uri bilan ClientRegistration ni sozlash orqali amalga oshirilishi mumkin, quyidagi misolda ko'rsatilgan:

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: okta-client-id
            client-secret: okta-client-secret
            ...
        provider:
          okta:
            issuer-uri: https://dev-1234.oktapreview.com

…va OidcClientInitiatedLogoutSuccessHandler, client tomonidan boshlatilgan chiqishni amalga oshiradi, quyidagicha sozlanishi mumkin:

Java
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
	@Autowired
	private ClientRegistrationRepository clientRegistrationRepository;
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorize -> authorize
				.anyRequest().authenticated()
			)
			.oauth2Login(withDefaults())
			.logout(logout -> logout
				.logoutSuccessHandler(oidcLogoutSuccessHandler())
			);
		return http.build();
	}
	private LogoutSuccessHandler oidcLogoutSuccessHandler() {
		OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler =
				new OidcClientInitiatedLogoutSuccessHandler(this.clientRegistrationRepository);
		// Foydalanuvchi agentining joylashuvi, xizmat ko'rsatuvchidan chiqqandan so'ng, ko'chirilishi kerak bo'lgan manzilni o'rnatadi
		oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
		return oidcLogoutSuccessHandler;
	}
}
Kotlin
@EnableWebSecurity
class OAuth2LoginSecurityConfig {
    @Autowired
    private lateinit var clientRegistrationRepository: ClientRegistrationRepository
    @Bean
    open fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeRequests {
                authorize(anyRequest, authenticated)
            }
            oauth2Login { }
            logout {
                logoutSuccessHandler = oidcLogoutSuccessHandler()
            }
        }
        return http.build()
    }
    private fun oidcLogoutSuccessHandler(): LogoutSuccessHandler {
        val oidcLogoutSuccessHandler = OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository)
        // Foydalanuvchi agentining joylashuvi, xizmat ko'rsatuvchidan chiqqandan so'ng, ko'chirilishi kerak bo'lgan manzilni o'rnatadi
        oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}")
        return oidcLogoutSuccessHandler
    }
}
OidcClientInitiatedLogoutSuccessHandler {baseUrl} ploshchadkasini qo'llab-quvvatlaydi. Asosiy URL manzil holatida, masalan, app.example.org, uni so'rov paytida almashtiradi.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION