OAuth 2.0 Resource Server 권한 구현 - 권한 구성 커스터마이징
Last updated
Last updated
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain1(HttpSecurity http) throws Exception {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(new CustomRoleConverter());
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/photos/1").hasAuthority("ROLE_photo")
.requestMatchers("/photos/3").hasAuthority("ROLE_default-roles-oauth2")
.anyRequest().authenticated()
)
.oauth2ResourceServer(config -> config
.jwt(jwt -> jwt
.jwtAuthenticationConverter(converter)))
;
return http.build();
}
@Bean
@Order(1)
public SecurityFilterChain securityFilterChain2(HttpSecurity http) throws Exception {
http
.securityMatchers(matchers -> matchers.requestMatchers("/photos/2"))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/photos/2").hasAuthority("SCOPE_photo")
.anyRequest().authenticated()
)
.oauth2ResourceServer(config -> config.jwt(Customizer.withDefaults()))
;
return http.build();
}
}public class CustomRoleConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
private final String ROLE_PREFIX = "ROLE_";
@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
String scopes = jwt.getClaimAsString("scope");
Map<String, Object> realmAccess = jwt.getClaimAsMap("realm_access");
if (scopes == null || realmAccess == null) {
return Collections.emptyList();
}
//기존 scope 정보에 ROLE_ 접두사 추가
Collection<GrantedAuthority> authorities1 = Arrays.stream(scopes.split(" "))
.map(roleName -> ROLE_PREFIX + roleName)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
//추가적으로 roles 정보로 새로운 권한 추가
Collection<GrantedAuthority> authorities2 = ((List<String>) realmAccess.get("roles")).stream()
.map(roleName -> ROLE_PREFIX + roleName)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
authorities1.addAll(authorities2);
return authorities1;
}
}