Spring Boot集成Okta:如何获取用户所属组
在Spring Boot + Okta OIDC中获取用户所属组
要从Okta获取用户组,需先在Okta控制台配置组声明,再在Spring Boot应用中配置并提取组信息,具体步骤如下:
一、Okta控制台配置组声明
- 登录Okta管理控制台,进入你的OIDC应用
- 切换到Sign On标签页,找到OpenID Connect ID Token配置项,点击Edit
- 在Claims区域点击Add Claim:
- Name:填写
groups(自定义名称需和后续代码对应) - Include in token type:选择
ID Token或UserInfo(按需选择) - Value type:选择
Groups - Filter:设置组过滤规则(比如填
.*表示包含所有组,或指定特定组) - 保存配置
- Name:填写
二、Spring Boot应用配置
在application.yml(或application.properties)中补充配置,确保Spring Security能正确解析组信息:
spring: security: oauth2: client: registration: okta: client-id: ${OKTA_CLIENT_ID} client-secret: ${OKTA_CLIENT_SECRET} scope: openid, profile, email, groups # 新增groups scope provider: okta: issuer-uri: https://your-okta-domain.com/oauth2/default resourceserver: jwt: issuer-uri: https://your-okta-domain.com/oauth2/default
如果是OAuth2客户端模式,确保scope包含groups即可。
三、代码中获取用户组
方法1:直接从OAuth2User Attributes提取
若Okta已将组放入ID Token的claims中,可直接从OAuth2User的属性里获取:
修改你现有的UserController,添加组获取逻辑:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Collection; import java.util.List; import java.util.Map; @RestController public class UserController { @GetMapping("/print-username") public ResponseEntity<String> printUsername(@AuthenticationPrincipal OAuth2User principal) { if (principal == null) { return new ResponseEntity<>("User not authenticated", HttpStatus.UNAUTHORIZED); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("User Attributes:\n"); // 打印用户属性 Map<String, Object> attributes = principal.getAttributes(); for (Map.Entry<String, Object> entry : attributes.entrySet()) { stringBuilder.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } System.out.println(stringBuilder.toString()); // 获取并打印用户组 List<String> groups = (List<String>) attributes.get("groups"); if (groups != null && !groups.isEmpty()) { System.out.println("User Groups:"); for (String group : groups) { System.out.println("- " + group); } } else { System.out.println("No groups found for user"); } // 打印用户权限 Collection<? extends GrantedAuthority> authorities = principal.getAuthorities(); for (GrantedAuthority authority : authorities) { System.out.println("Authority: " + authority.getAuthority()); } // 获取用户名 String username = (String) attributes.get("email"); System.out.println("Username: " + username); return new ResponseEntity<>("User info printed in the server console", HttpStatus.OK); } }
方法2:自定义OAuth2UserService将组转为权限
如果需要把组映射为Spring Security的GrantedAuthority,可以自定义用户服务:
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service public class CustomOktaOAuth2UserService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); Map<String, Object> attributes = oAuth2User.getAttributes(); // 提取组列表 List<String> groups = (List<String>) attributes.get("groups"); // 将组转为GrantedAuthority,可自定义前缀 List<SimpleGrantedAuthority> authorities = groups.stream() .map(group -> new SimpleGrantedAuthority("ROLE_" + group.toUpperCase())) .collect(Collectors.toList()); // 添加默认权限 authorities.add(new SimpleGrantedAuthority("ROLE_USER")); return new DefaultOAuth2User(authorities, attributes, "email"); } }
然后在Spring Security配置类中注册这个自定义服务:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { private final CustomOktaOAuth2UserService customOktaOAuth2UserService; public SecurityConfig(CustomOktaOAuth2UserService customOktaOAuth2UserService) { this.customOktaOAuth2UserService = customOktaOAuth2UserService; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .userService(customOktaOAuth2UserService) ) ); return http.build(); } }
配置完成后,principal.getAuthorities()中会包含组对应的权限(比如用户属于admin组,会生成ROLE_ADMIN权限)。
内容的提问来源于stack exchange,提问作者Jack BeNimble
相关产品推荐
相关产品推荐

