77import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
88import org .springframework .boot .autoconfigure .condition .ConditionalOnExpression ;
99import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
10+ import org .springframework .boot .context .event .ApplicationStartedEvent ;
1011import org .springframework .context .annotation .Bean ;
1112import org .springframework .context .annotation .Configuration ;
13+ import org .springframework .context .event .EventListener ;
14+ import org .springframework .context .expression .MapAccessor ;
1215import org .springframework .core .annotation .Order ;
16+ import org .springframework .expression .spel .standard .SpelExpressionParser ;
17+ import org .springframework .expression .spel .support .SimpleEvaluationContext ;
1318import org .springframework .security .config .Customizer ;
1419import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
1520import org .springframework .security .config .annotation .web .configurers .AbstractHttpConfigurer ;
1823import org .springframework .security .oauth2 .client .registration .ClientRegistration ;
1924import org .springframework .security .oauth2 .client .registration .ClientRegistrationRepository ;
2025import org .springframework .security .oauth2 .client .registration .InMemoryClientRegistrationRepository ;
26+ import org .springframework .security .oauth2 .client .userinfo .DefaultOAuth2UserService ;
2127import org .springframework .security .oauth2 .core .AuthorizationGrantType ;
2228import org .springframework .security .web .SecurityFilterChain ;
2329
2733
2834@ Log
2935@ Configuration
30- public class SecurityConfig {
36+ public class SecurityConfig extends DefaultOAuth2UserService {
3137 @ Bean
3238 @ ConditionalOnExpression ("#{!(systemEnvironment['DEBUG']?:'false').equals('true')}" )
3339 public @ Nullable ClientRegistrationRepository clientRegistrationRepository (@ Autowired AppConfig config ) {
@@ -54,9 +60,12 @@ public class SecurityConfig {
5460 public SecurityFilterChain configureSecure (HttpSecurity http ) throws Exception {
5561 log .info ("Using OAuth2-based SecurityFilterChain" );
5662 return http .authorizeHttpRequests (auth -> auth .requestMatchers ("/api/**" )
57- .fullyAuthenticated ()
58- .anyRequest ()
59- .authenticated ()).oauth2Login (Customizer .withDefaults ()).csrf (AbstractHttpConfigurer ::disable ).build ();
63+ .fullyAuthenticated ()
64+ .anyRequest ()
65+ .authenticated ())
66+ .oauth2Login (oauth -> oauth .userInfoEndpoint (info -> info .userService (this )))
67+ .csrf (AbstractHttpConfigurer ::disable )
68+ .build ();
6069 }
6170
6271 @ Bean
@@ -70,8 +79,6 @@ public SecurityFilterChain configureInsecure(HttpSecurity http) throws Exception
7079 .permitAll ()).httpBasic (Customizer .withDefaults ()).userDetailsService (username -> new UserDetails () {
7180 // token for dev: ZGV2Og==
7281
73- {}
74-
7582 @ Override
7683 public Collection <? extends GrantedAuthority > getAuthorities () {
7784 return List .of ();
@@ -88,4 +95,20 @@ public String getUsername() {
8895 }
8996 }).csrf (AbstractHttpConfigurer ::disable ).build ();
9097 }
98+
99+ @ EventListener
100+ public void on (ApplicationStartedEvent ignored ) {
101+ setAttributesConverter (input -> source -> {
102+ if (!source .containsKey ("ocs" )) return source ;
103+ var userId = new SpelExpressionParser ().parseRaw ("ocs.data.id" )
104+ .getValue (SimpleEvaluationContext .forPropertyAccessors (new MapAccessor ())
105+ .withRootObject (source )
106+ .build ());
107+ source .put (input .getClientRegistration ()
108+ .getProviderDetails ()
109+ .getUserInfoEndpoint ()
110+ .getUserNameAttributeName (), userId );
111+ return source ;
112+ });
113+ }
91114}
0 commit comments