mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Make OAuth request scopes & roles claim configurable (#689)
* Request OAuth scope "roles" by default * Make OAuth request scopes configurable * Make roles claim configurable
This commit is contained in:
@@ -49,7 +49,7 @@ function SsoManagementLayout({getConfig, formik, setSaveMessage}: any) {
|
|||||||
<ConfigFormField configElement={getConfig("sso.oidc.enabled")}/>
|
<ConfigFormField configElement={getConfig("sso.oidc.enabled")}/>
|
||||||
|
|
||||||
<Section title="SSO user handling"/>
|
<Section title="SSO user handling"/>
|
||||||
<div className="flex flex-row items-baseline">
|
<div className="flex flex-row items-baseline mb-4">
|
||||||
<CheckboxGroup className="flex flex-col flex-1 items-baseline gap-2"
|
<CheckboxGroup className="flex flex-col flex-1 items-baseline gap-2"
|
||||||
value={["auto-register-new-users"]}>
|
value={["auto-register-new-users"]}>
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-row gap-2">
|
||||||
@@ -70,6 +70,13 @@ function SsoManagementLayout({getConfig, formik, setSaveMessage}: any) {
|
|||||||
!formik.values.sso.oidc["auto-register-new-users"]}/>
|
!formik.values.sso.oidc["auto-register-new-users"]}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-row items-center gap-4">
|
||||||
|
<ConfigFormField configElement={getConfig("sso.oidc.roles-claim")}
|
||||||
|
isDisabled={!formik.values.sso.oidc.enabled}/>
|
||||||
|
<ConfigFormField configElement={getConfig("sso.oidc.oauth-scopes")}
|
||||||
|
isDisabled={!formik.values.sso.oidc.enabled}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Section title="SSO provider configuration"/>
|
<Section title="SSO provider configuration"/>
|
||||||
<ConfigFormField configElement={getConfig("sso.oidc.client-id")}
|
<ConfigFormField configElement={getConfig("sso.oidc.client-id")}
|
||||||
isDisabled={!formik.values.sso.oidc.enabled}/>
|
isDisabled={!formik.values.sso.oidc.enabled}/>
|
||||||
|
|||||||
@@ -147,6 +147,20 @@ sealed class ConfigProperties<T : Serializable>(
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data object RolesClaim : ConfigProperties<String>(
|
||||||
|
String::class,
|
||||||
|
"sso.oidc.roles-claim",
|
||||||
|
"JWT claim to extract roles from",
|
||||||
|
"roles"
|
||||||
|
)
|
||||||
|
|
||||||
|
data object OAuthScopes : ConfigProperties<Array<String>>(
|
||||||
|
Array<String>::class,
|
||||||
|
"sso.oidc.oauth-scopes",
|
||||||
|
"OAuth2 scopes to request",
|
||||||
|
arrayOf("openid", "profile", "email", "roles")
|
||||||
|
)
|
||||||
|
|
||||||
data object ClientId : ConfigProperties<String>(
|
data object ClientId : ConfigProperties<String>(
|
||||||
String::class,
|
String::class,
|
||||||
"sso.oidc.client-id",
|
"sso.oidc.client-id",
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class SecurityConfig(
|
|||||||
val clientRegistration = ClientRegistration.withRegistrationId(SSO_PROVIDER_KEY)
|
val clientRegistration = ClientRegistration.withRegistrationId(SSO_PROVIDER_KEY)
|
||||||
.clientId(config.get(ConfigProperties.SSO.OIDC.ClientId))
|
.clientId(config.get(ConfigProperties.SSO.OIDC.ClientId))
|
||||||
.clientSecret(config.get(ConfigProperties.SSO.OIDC.ClientSecret))
|
.clientSecret(config.get(ConfigProperties.SSO.OIDC.ClientSecret))
|
||||||
.scope("openid", "profile", "email")
|
.scope(config.get(ConfigProperties.SSO.OIDC.OAuthScopes)?.toList())
|
||||||
.userNameAttributeName("preferred_username")
|
.userNameAttributeName("preferred_username")
|
||||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||||
.issuerUri(config.get(ConfigProperties.SSO.OIDC.IssuerUrl))
|
.issuerUri(config.get(ConfigProperties.SSO.OIDC.IssuerUrl))
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.gameyfin.app.users
|
package org.gameyfin.app.users
|
||||||
|
|
||||||
|
import org.gameyfin.app.config.ConfigProperties
|
||||||
|
import org.gameyfin.app.config.ConfigService
|
||||||
import org.gameyfin.app.core.Role
|
import org.gameyfin.app.core.Role
|
||||||
import org.gameyfin.app.users.entities.User
|
import org.gameyfin.app.users.entities.User
|
||||||
import org.gameyfin.app.users.persistence.UserRepository
|
import org.gameyfin.app.users.persistence.UserRepository
|
||||||
@@ -11,7 +13,8 @@ import org.springframework.stereotype.Service
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
class RoleService(
|
class RoleService(
|
||||||
private val userRepository: UserRepository
|
private val userRepository: UserRepository,
|
||||||
|
private val configService: ConfigService
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -66,7 +69,8 @@ class RoleService(
|
|||||||
.filterIsInstance<OidcUserAuthority>()
|
.filterIsInstance<OidcUserAuthority>()
|
||||||
.flatMap { oidcUserAuthority ->
|
.flatMap { oidcUserAuthority ->
|
||||||
val userInfo = oidcUserAuthority.userInfo
|
val userInfo = oidcUserAuthority.userInfo
|
||||||
val roles = userInfo.getClaim<List<String>>("roles") ?: return@flatMap emptySequence()
|
val rolesClaim = configService.get(ConfigProperties.SSO.OIDC.RolesClaim)
|
||||||
|
val roles = userInfo.getClaim<List<String>>(rolesClaim) ?: return@flatMap emptySequence()
|
||||||
roles.asSequence().mapNotNull {
|
roles.asSequence().mapNotNull {
|
||||||
if (it.startsWith(SSO_ROLE_PREFIX)) SimpleGrantedAuthority(
|
if (it.startsWith(SSO_ROLE_PREFIX)) SimpleGrantedAuthority(
|
||||||
it.replace(SSO_ROLE_PREFIX, INTERNAL_ROLE_PREFIX)
|
it.replace(SSO_ROLE_PREFIX, INTERNAL_ROLE_PREFIX)
|
||||||
|
|||||||
Reference in New Issue
Block a user