### OAuth2 Client and Proxy Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2AuthenticationWebFilter.md Example configuration for OAuth2 client registration (e.g., GitHub) and proxy settings within the application.yaml file. This setup is necessary for the HaloOAuth2AuthenticationWebFilter to function correctly. ```yaml spring: security: oauth2: client: registration: github: clientId: "your-client-id" clientSecret: "your-client-secret" scope: "repo,user" oauth2: proxy: enabled: true host: "proxy.company.com" port: 8080 username: "proxyuser" password: "proxypass" connect-timeout-millis: 10000 ``` -------------------------------- ### OauthGithubPlugin start() Method Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthGithubPlugin.md Registers AuthorizedClient and Oauth2ClientRegistration extension schemes when the plugin is started. ```java @Override public void start() ``` -------------------------------- ### OauthGithubPlugin Example Usage Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthGithubPlugin.md Illustrates the lifecycle of the OauthGithubPlugin during Halo startup and shutdown, including automatic instantiation and scheme registration/unregistration. ```java // The plugin is instantiated by Spring automatically // when Halo loads the plugin. No direct instantiation is needed. // During Halo startup: // 1. OauthGithubPlugin is created with dependencies injected // 2. Halo calls start() when the plugin is enabled // 3. Extension schemes are registered and become available // 4. OAuth2 authentication becomes functional // During Halo shutdown: // 1. Halo calls stop() when the plugin is disabled // 2. Extension schemes are unregistered // 3. OAuth2 authentication is no longer available ``` -------------------------------- ### Oauth2UserProfile Builder Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfile.md Demonstrates how to construct an Oauth2UserProfile instance using the builder pattern provided by Lombok. ```java Oauth2UserProfile profile = Oauth2UserProfile.builder() .username("johndoe") .displayName("John Doe") .profileUrl("https://github.com/johndoe") .avatarUrl("https://avatars.githubusercontent.com/u/12345?v=4") .build(); ``` -------------------------------- ### Social Connection Flow Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/SocialServerOauth2AuthorizationRequestResolver.md Illustrates the user flow for connecting an OAuth2 account, highlighting how the resolver adds a 'social_connection=true' parameter. ```text User Action: Click "Connect GitHub account" ↓ Frontend navigates to: /oauth2/authorization/github?social_connection=true ↓ SocialServerOauth2AuthorizationRequestResolver intercepts ↓ Builds standard authorization request ↓ Adds: social_connection=true to additionalParameters ↓ Redirects to: https://github.com/login/oauth/authorize?... ↓ (GitHub ignores the unknown parameter) ↓ GitHub redirects back to: /login/oauth2/code/github?code=...&state=...&social_connection=true ↓ Application identifies this as social connection (not login) ↓ Associates GitHub account with existing Halo user ``` -------------------------------- ### Create and Configure AuthorizedClient Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/AuthorizedClient.md Demonstrates how to create a new AuthorizedClient extension instance and populate its specification with OAuth2 credentials and token details. This example shows setting metadata, registration ID, principal name, token values, and timestamps. ```java // Creating a new AuthorizedClient extension AuthorizedClient authorizedClient = new AuthorizedClient(); authorizedClient.setMetadata(new Metadata()); authorizedClient.getMetadata().setName("github-johndoe"); AuthorizedClient.AuthorizedClientSpec spec = new AuthorizedClient.AuthorizedClientSpec(); spec.setRegistrationId("github"); spec.setPrincipalName("johndoe"); spec.setAccessTokenType("Bearer"); spec.setAccessTokenValue("ghu_1234567890abcdef"); spec.setAccessTokenIssuedAt(Instant.now()); spec.setAccessTokenExpiresAt(Instant.now().plusSeconds(3600)); spec.setAccessTokenScopes("repo,user"); spec.setRefreshTokenValue("ghr_refresh_token_value"); spec.setRefreshTokenIssuedAt(Instant.now()); authorizedClient.setSpec(spec); // The authorized client is stored and managed by DefaultOAuth2AuthorizedClientService // which handles persistence and retrieval through the Halo extension system ``` -------------------------------- ### NotFoundException Usage Examples Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/errors.md Illustrates using NotFoundException to handle cases where an OAuth2 client registration or provider is not found, including error handling and service implementation scenarios. ```java // Checking for existence before processing try { ClientRegistration registration = clientRepository .findByRegistrationId("github") .block(); } catch (NotFoundException e) { System.err.println("GitHub provider not configured: " + e.getReason()); // Handle missing provider configuration } // In service implementation Oauth2ClientRegistration registration = client .fetch(Oauth2ClientRegistration.class, registrationId) .switchIfEmpty(Mono.error(new NotFoundException( "Oauth2 client registration " + registrationId + " not found" ))) .block(); ``` -------------------------------- ### Configure Custom SSO with OpenID Connect Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2ClientRegistration.md Extends the previous example to configure custom SSO providers supporting OpenID Connect. It adds issuer URI and JWK set URI for OIDC compliance. Use this when integrating with OIDC-compliant identity providers. ```java // For custom SSO providers with OpenID Connect support spec.setIssuerUri("https://custom-sso.example.com"); spec.setJwkSetUri("https://custom-sso.example.com/.well-known/jwks.json"); ``` -------------------------------- ### AccessDeniedException Usage Examples Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/errors.md Demonstrates how to throw AccessDeniedException, both with a simple reason and with i18n support for detailed error messages. ```java if (!userHasPermission(user, resource)) { throw new AccessDeniedException("User does not have permission to access this resource"); } // With i18n support throw new AccessDeniedException( "User does not have permission", "access.denied.user.role", new Object[]{"admin", resource.getName()} ); ``` -------------------------------- ### Missing Host Configuration Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/errors.md This YAML configuration shows a scenario where the OAuth2 proxy is enabled, but the host is not specified. This will result in a Spring Boot startup failure due to a missing required field. ```yaml oauth2: proxy: enabled: true port: 8080 # host is missing ``` -------------------------------- ### Programmatic Access to OAuth2 Client Registration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Demonstrates how to programmatically access the OauthClientRegistrationRepository to retrieve client registration details, such as for the 'github' provider. This example shows how to inject the repository and use its methods to find a registration by ID. ```java import org.springframework.stereotype.Service; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import reactor.core.publisher.Mono; // The repository is used by Spring Security internally // typically through the ReactiveClientRegistrationRepository interface // Example: Programmatic access (if needed) @Service public class OAuth2Service { private final OauthClientRegistrationRepository repository; public OAuth2Service(OauthClientRegistrationRepository repository) { this.repository = repository; } public Mono getGithubRegistration() { return repository.findByRegistrationId("github") .doOnNext(reg -> System.out.println("Found: " + reg.getClientName())) .doOnError(e -> System.err.println("Error: " + e.getMessage())); } } // The repository automatically handles: // 1. Loading OAuth2ClientRegistration extension // 2. Loading GenericClientConf or SsoClientConf from ConfigMap // 3. Applying external URL configuration // 4. Converting all string config to Spring types ``` -------------------------------- ### OAuth2UserService Usage Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfileMapperManager.md This example demonstrates how to inject and use the Oauth2UserProfileMapperManager within a Spring service to map an OAuth2User to a standardized Oauth2UserProfile. It includes error handling for unsupported providers. ```java // Inject the manager @Service public class OAuth2UserService { private final Oauth2UserProfileMapperManager mapperManager; public OAuth2UserService(Oauth2UserProfileMapperManager mapperManager) { this.mapperManager = mapperManager; } public Oauth2UserProfile extractUserProfile(String provider, OAuth2User oauth2User) { try { // Map the OAuth2User to standardized profile Oauth2UserProfile profile = mapperManager.mapProfile(provider, oauth2User); // Use the standardized profile System.out.println("Username: " + profile.getUsername()); System.out.println("Display Name: " + profile.getDisplayName()); System.out.println("Avatar: " + profile.getAvatarUrl()); return profile; } catch (IllegalArgumentException e) { // Handle unsupported provider System.err.println("Provider not supported: " + provider); throw e; } } } ``` -------------------------------- ### OAuth2 Proxy Validation Errors Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Examples of validation errors that can occur during startup if the proxy configuration is invalid. These errors indicate issues with host, port, or timeout settings. ```text Port must be between 1 and 65535 Host cannot be blank when proxy is enabled Connect timeout must be greater than zero ``` -------------------------------- ### Create GitHub OAuth2 Client Registration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2ClientRegistration.md Example of creating an Oauth2ClientRegistration object for GitHub. It demonstrates setting client authentication, grant type, authorization/token URIs, user info endpoint, and scopes. This snippet shows how to programmatically configure a specific OAuth2 provider. ```java // Creating a GitHub OAuth2 client registration Oauth2ClientRegistration registration = new Oauth2ClientRegistration(); registration.setMetadata(new Metadata()); registration.getMetadata().setName("github"); Oauth2ClientRegistration.Oauth2ClientRegistrationSpec spec = new Oauth2ClientRegistration.Oauth2ClientRegistrationSpec(); spec.setClientName("GitHub OAuth"); spec.setClientAuthenticationMethod("client_secret_basic"); spec.setAuthorizationGrantType("authorization_code"); spec.setAuthorizationUri("https://github.com/login/oauth/authorize"); spec.setTokenUri("https://github.com/login/oauth/access_token"); spec.setUserInfoUri("https://api.github.com/user"); spec.setUserNameAttributeName("login"); spec.setScopes(Set.of("repo", "user")); spec.setRedirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}"); registration.setSpec(spec); ``` -------------------------------- ### GenericUserProfileMapper Usage Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/GenericUserProfileMapper.md Demonstrates how to use the GenericUserProfileMapper to check provider support and map an OAuth2 user profile during an authentication flow. The mapper automatically handles attribute extraction for supported providers. ```java // During OAuth2 authentication flow OAuth2User oauth2User = getUserFromAuthorizationProvider(); // The mapper is automatically selected and used GenericUserProfileMapper mapper = new GenericUserProfileMapper(); boolean supportsGithub = mapper.supports("github"); // true boolean supportsGitlab = mapper.supports("gitlab"); // true boolean supportsCustom = mapper.supports("custom-sso"); // true // Map the user profile Oauth2UserProfile profile = mapper.mapProfile(oauth2User); // Access the extracted information String username = profile.getUsername(); // "octocat" String displayName = profile.getDisplayName(); // "The Octocat" String profileUrl = profile.getProfileUrl(); // "https://github.com/octocat" String avatarUrl = profile.getAvatarUrl(); // "https://avatars.githubusercontent.com/u/1?v=4" ``` -------------------------------- ### Custom Oauth2UserProfileMapper Implementation Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/GenericUserProfileMapper.md Example of creating a custom mapper for a specific provider ('custom-sso'). This class implements Oauth2UserProfileMapper, defines custom attribute extraction in mapProfile, and specifies provider support in supports. ```java @Component @Order(1) // Higher priority than generic mapper (default order 0) public class CustomSSOMapper implements Oauth2UserProfileMapper { @Override public Oauth2UserProfile mapProfile(OAuth2User oauth2User) { return Oauth2UserProfile.builder() .username(oauth2User.getAttribute("sub")) // OIDC standard .displayName(oauth2User.getAttribute("given_name")) .profileUrl(oauth2User.getAttribute("profile")) .avatarUrl(oauth2User.getAttribute("picture")) .build(); } @Override public boolean supports(String registrationId) { return "custom-sso".equals(registrationId); } } ``` -------------------------------- ### DefaultOAuth2AuthorizedClientService Usage Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/DefaultOAuth2AuthorizedClientService.md Demonstrates how to inject and use DefaultOAuth2AuthorizedClientService for saving, loading, and removing OAuth2 tokens. This service is essential for managing user authentication and authorization flows. ```java // Inject the service @Service public class OAuth2TokenService { private final DefaultOAuth2AuthorizedClientService authorizedClientService; public OAuth2TokenService(DefaultOAuth2AuthorizedClientService service) { this.authorizedClientService = service; } // Save tokens after authentication public Mono storeTokens(OAuth2AuthorizedClient client, Authentication auth) { return authorizedClientService.saveAuthorizedClient(client, auth) .doOnSuccess(v -> System.out.println("Tokens saved for: " + auth.getName())); } // Load tokens for API calls public Mono getAccessToken(String provider, String username) { return authorizedClientService.loadAuthorizedClient(provider, username) .map(client -> client.getAccessToken().getTokenValue()); } // Remove tokens when user disconnects public Mono disconnectProvider(String provider, String username) { return authorizedClientService.removeAuthorizedClient(provider, username) .doOnSuccess(v -> System.out.println("Disconnected: " + provider)); } } // Example: Using the service during authentication public Mono onOAuth2AuthenticationSuccess( OAuth2AuthorizedClient authorizedClient, Authentication principal) { return authorizedClientService.saveAuthorizedClient(authorizedClient, principal) .then(Mono.fromRunnable(() -> System.out.println("User " + principal.getName() + " authenticated via " + authorizedClient.getClientRegistration().getClientName()) )); } ``` -------------------------------- ### Spring Security Configuration for OAuth2 Resolver Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/SocialServerOauth2AuthorizationRequestResolver.md Shows how to configure the SocialServerOauth2AuthorizationRequestResolver within a Spring Security setup for a reactive web application. ```java @Configuration @EnableWebFluxSecurity public class SecurityConfig { @Bean public ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver( ReactiveClientRegistrationRepository clientRegistrationRepository) { return new SocialServerOauth2AuthorizationRequestResolver( clientRegistrationRepository); } @Bean public SecurityWebFilterChain securityWebFilterChain( ServerHttpSecurity http, ServerOAuth2AuthorizationRequestResolver resolver) { http .oauth2Client(oauth2 -> oauth2 .authorizationRequestResolver(resolver) ); return http.build(); } } ``` -------------------------------- ### Handle OAuth2AuthenticationException for Disabled Provider Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/errors.md This example shows how `OAuth2AuthenticationException` is thrown when a user attempts to log in using an OAuth2 provider that is disabled in the system settings. This results in a 401 Unauthorized error. ```java if (!enabledNames.contains(registrationId)) { throw new OAuth2AuthenticationException( "Authentication provider is not enabled: " + registrationId); } ``` -------------------------------- ### UserConnectionDisconnectedListener Usage Example Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/UserConnectionDisconnectedListener.md This listener is automatically registered and invoked when a UserConnectionDisconnectedEvent is published. No direct invocation is needed. The example demonstrates the user's perspective of disconnecting a service and how to verify credential cleanup. ```java // The listener is automatically registered when the plugin starts // No direct invocation is needed // Example: User perspective // 1. User logs into Halo // 2. User goes to account settings / connected accounts // 3. User clicks "Disconnect GitHub" // 4. Halo publishes UserConnectionDisconnectedEvent // 5. UserConnectionDisconnectedListener.onApplicationEvent() is called // 6. OAuth2 tokens are cleaned up // 7. User can no longer use GitHub for accessing Halo APIs // 8. User can reconnect GitHub later by linking account again // Example: Checking if credentials are cleaned up @Service public class OAuth2CredentialService { private final DefaultOAuth2AuthorizedClientService clientService; public OAuth2CredentialService(DefaultOAuth2AuthorizedClientService clientService) { this.clientService = clientService; } public Mono hasGitHubCredentials(String username) { return clientService.loadAuthorizedClient("github", username) .map(client -> true) .defaultIfEmpty(false); } } // After user disconnects GitHub: // hasGitHubCredentials("johndoe") returns false ``` -------------------------------- ### Create OAuth Client Registration Repository Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md Creates the client registration repository using provided extension client and external URL supplier. ```java return new OauthClientRegistrationRepository(extensionClient, externalUrlSupplier); ``` -------------------------------- ### Custom Parameters Handling Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/SocialServerOauth2AuthorizationRequestResolver.md Demonstrates how the resolver generically handles and includes custom query parameters in the authorization request. ```text Request: /oauth2/authorization/github?param1=value1¶m2=value2&social_connection=true ↓ Parameters added to authorization request: - param1: value1 - param2: value2 - social_connection: true ↓ Authorization redirect includes all parameters ``` -------------------------------- ### Oauth2LoginConfiguration Class Definition Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md Defines the Oauth2LoginConfiguration class, a Spring configuration component for OAuth2 login setup. It enables asynchronous operations and configuration properties. ```java @Slf4j @Getter @Configuration @EnableAsync @EnableConfigurationProperties(OAuth2Properties.class) public class Oauth2LoginConfiguration ``` -------------------------------- ### Project File Structure Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/INDEX.md Overview of the directory and file layout for the Plugin OAuth2 project. This structure helps in navigating the documentation and understanding the organization of different components. ```text output/ ├── README.md # Overview and quick reference ├── INDEX.md # This file ├── types.md # Type definitions and interfaces ├── configuration.md # Configuration options ├── errors.md # Exception classes and errors └── api-reference/ # Component documentation ├── OauthGithubPlugin.md ├── Oauth2LoginConfiguration.md ├── OauthClientRegistrationRepository.md ├── DefaultOAuth2AuthorizedClientService.md ├── HaloOAuth2AuthenticationWebFilter.md ├── HaloOAuth2RedirectWebFilter.md ├── Oauth2UserProfileMapper.md ├── GenericUserProfileMapper.md ├── Oauth2UserProfileMapperManager.md ├── AuthorizedClient.md ├── Oauth2ClientRegistration.md ├── Oauth2UserProfile.md ├── SocialServerOauth2AuthorizationRequestResolver.md └── UserConnectionDisconnectedListener.md ``` -------------------------------- ### HaloOAuth2RedirectWebFilter Constructor Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2RedirectWebFilter.md Initializes the HaloOAuth2RedirectWebFilter with the necessary OAuth2 login configuration. This configuration includes details like the client registration repository and request cache. ```java public HaloOAuth2RedirectWebFilter(Oauth2LoginConfiguration configuration) ``` -------------------------------- ### Creating and Accessing Oauth2UserProfile Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfile.md Shows how to create Oauth2UserProfile instances, including a minimal one with only required fields, and how to access its immutable properties. ```java // Creating a user profile from GitHub OAuth2 response Oauth2UserProfile githubProfile = Oauth2UserProfile.builder() .username("octocat") .displayName("The Octocat") .profileUrl("https://github.com/octocat") .avatarUrl("https://avatars.githubusercontent.com/u/1?v=4") .build(); // Creating a minimal profile with only required fields Oauth2UserProfile minimalProfile = Oauth2UserProfile.builder() .username("user123") .displayName("User Name") .build(); // Accessing properties (immutable) String username = githubProfile.getUsername(); // "octocat" String displayName = githubProfile.getDisplayName(); // "The Octocat" String profileUrl = githubProfile.getProfileUrl(); // "https://github.com/octocat" String avatarUrl = githubProfile.getAvatarUrl(); // "https://avatars.githubusercontent.com/u/1?v=4" ``` -------------------------------- ### Custom Request Cache Configuration for OAuth2 Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md Provides an example of configuring a custom request cache for OAuth2 flows. The Oauth2LoginConfiguration will automatically use the custom cache if provided as a Spring Bean. ```java // Example: Custom request cache configuration @Configuration public class CustomRequestCacheConfig { @Bean public ServerRequestCache customRequestCache() { // Return custom implementation return new CustomServerRequestCache(); } } // The Oauth2LoginConfiguration will automatically use the custom cache ``` -------------------------------- ### Enable and Configure GitHub OAuth2 Provider via kubectl Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Use this command to enable a GitHub OAuth2 provider and configure its credentials using Kubernetes resources. ```bash kubectl apply -f - < { var builder = typeSpec.type(ProxyProvider.Proxy.HTTP) .host(proxy.getHost()) .port(proxy.getPort()); if (StringUtils.hasText(proxy.getUsername())) { builder.username(proxy.getUsername()) .password(u -> proxy.getPassword()); } if (proxy.getConnectTimeoutMillis() != null && proxy.getConnectTimeoutMillis() > 0) { builder.connectTimeoutMillis(proxy.getConnectTimeoutMillis()); } }); } ``` -------------------------------- ### Typical Mapping Process with OAuth2User Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfile.md Illustrates the typical process of mapping an OAuth2User object, received from a Spring Security authorization provider, to an Oauth2UserProfile using a mapper. ```java // OAuth2User received from Spring Security OAuth2User oauth2User; // From authorization provider // Mapper converts provider response to standard profile Oauth2UserProfile profile = mapper.mapProfile(oauth2User); // Returns: Oauth2UserProfile with extracted username, displayName, etc. // The profile is then used to identify or create Halo users ``` -------------------------------- ### SocialServerOauth2AuthorizationRequestResolver Constructor Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/SocialServerOauth2AuthorizationRequestResolver.md Initializes the resolver by calling the parent constructor with the provided client registration repository. ```java public SocialServerOauth2AuthorizationRequestResolver( ReactiveClientRegistrationRepository clientRegistrationRepository) ``` -------------------------------- ### SsoClientConf Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Configuration for custom SSO providers with full OpenID Connect support. Includes details like authorization, token, and user info URLs, scopes, and attribute mappings. ```APIDOC ## SsoClientConf ### Description Configuration for custom SSO providers with full OpenID Connect support. ### Fields - **clientId** (String) - Required - OAuth2 client ID. - **clientSecret** (String) - Required - OAuth2 client secret. - **authorizationUrl** (String) - Required - Provider's authorization endpoint. - **tokenUrl** (String) - Required - Provider's token endpoint. - **userInfoUrl** (String) - Required - Provider's user info endpoint. - **scopes** (String) - Required - Space or comma-separated list of scopes. - **userNameAttribute** (String) - Required - The claim/attribute name for user identification. - **issuerUri** (String) - Optional - OpenID Connect issuer URI. - **jwkSetUri** (String) - Optional - URL to the provider's JSON Web Key Set. ``` -------------------------------- ### Create Spring Security Authorized Client Repository Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md Creates Spring Security's authorized client repository, which depends on the authorized client service. ```java return new AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository( getAuthorizedClientService()); ``` -------------------------------- ### HTTP Proxy Configuration with Custom Timeout Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Configure this to route OAuth2 requests through an HTTP proxy with a custom connection timeout. Specify the timeout in milliseconds. ```yaml oauth2: proxy: enabled: true host: "proxy.company.com" port: 8080 connect-timeout-millis: 20000 ``` -------------------------------- ### supports Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/GenericUserProfileMapper.md Checks if this mapper supports a given OAuth2 provider. This implementation is designed to support all OAuth2 providers. ```APIDOC ## supports ### Description Indicates that this mapper supports all OAuth2 providers. ### Method Signature `boolean supports(String registrationId)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **registrationId** (String) - Required - The OAuth2 provider registration ID ### Returns `boolean` - Always returns true, indicating support for the provider. ### Throws `IllegalArgumentException` - If registrationId is null or blank. ### Purpose Acts as a fallback mapper for any provider, allowing the plugin to work with any OAuth2 provider out of the box. ### Implementation Example ```java Assert.hasText(registrationId, "Registration id must not be blank"); return true; ``` ``` -------------------------------- ### Oauth2UserProfileMapperManager Logic Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfileMapper.md Illustrates the core logic within Oauth2UserProfileMapperManager for selecting and applying an appropriate Oauth2UserProfileMapper based on the registration ID. ```java Oauth2UserProfile mapProfile(String registrationId, OAuth2User oauth2User) { return applicationContext.getBeanProvider(Oauth2UserProfileMapper.class) .orderedStream() .filter(mapper -> mapper.supports(registrationId)) .findFirst() .map(mapper -> mapper.mapProfile(oauth2User)) .orElseThrow(() -> new IllegalArgumentException( "No Oauth2UserProfileMapper found for registration id: " + registrationId)); } ``` -------------------------------- ### JavaScript for Programmatic OAuth2 Login Initiation Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2RedirectWebFilter.md This JavaScript function demonstrates how to programmatically initiate an OAuth2 login flow by redirecting the user's browser to the appropriate authorization URL. Pass the provider's registration ID to the function. ```javascript ``` -------------------------------- ### OauthGithubPlugin Constructor Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthGithubPlugin.md Initializes the OAuth2 plugin with necessary dependencies like PluginContext and SchemeManager, injected by Spring. ```java public OauthGithubPlugin(PluginContext pluginContext, SchemeManager schemeManager) ``` -------------------------------- ### fetchEnabledProviders Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Retrieves the set of enabled provider registration IDs from system settings. Returns an empty set if no settings are found. ```APIDOC ## fetchEnabledProviders ### Description Retrieves the set of enabled provider registration IDs from system settings. ### Returns - **Mono>** - A Mono emitting a set of enabled provider registration IDs. Returns an empty set if no settings are found. ``` -------------------------------- ### GenericClientConf Record Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Defines the configuration for generic OAuth2 providers. Use this for common providers like GitHub or GitLab. ```java record GenericClientConf(String clientId, String clientSecret) ``` -------------------------------- ### HTTP Proxy Configuration (No Authentication) Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Configure this to route OAuth2 requests through an HTTP proxy without requiring authentication. Specify the proxy host and port. ```yaml oauth2: proxy: enabled: true host: "proxy.company.com" port: 8080 ``` -------------------------------- ### Using GenericUserProfileMapper in Manager Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/GenericUserProfileMapper.md Demonstrates how the Oauth2UserProfileMapperManager utilizes the GenericUserProfileMapper to map user profiles. The manager discovers beans, finds the appropriate mapper, and calls its mapProfile method. ```java // In the manager's mapProfile method mapperManager.mapProfile("github", oauth2User); // 1. Discovers all Oauth2UserProfileMapperManager beans // 2. Finds this GenericUserProfileMapper supports "github" // 3. Calls mapProfile() on this mapper // 4. Returns the resulting Oauth2UserProfile ``` -------------------------------- ### OAuth2 Proxy Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/README.md Details the configuration properties for the OAuth2 proxy, including whether it's enabled and its connection details like host, port, and timeouts. ```text OAuth2Properties (Configuration) └── Proxy ├── enabled ├── host ├── port ├── username ├── password └── connectTimeoutMillis ``` -------------------------------- ### Proxy Configuration Class Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/types.md Defines the configuration settings for an HTTP proxy used when communicating with OAuth2 providers. This includes enabling the proxy, setting host, port, authentication credentials, and connection timeouts. Validation rules apply to port, host, and connection timeout if the proxy is enabled. ```java @Data public static class Proxy ``` -------------------------------- ### Authentication Success Handler Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2AuthenticationWebFilter.md Handles successful OAuth2 authentication by redirecting the user to the user center or the originally requested page. ```APIDOC ## Authentication Success Handler ### Description Redirects authenticated users to the user center. If a request was cached, it returns the user to the originally requested page. ### Path `/uc` (user center) ### Behavior - Redirects authenticated user to user center after successful authentication. - Uses configured request cache to return to originally requested page if available. ``` -------------------------------- ### SsoClientConf Record Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Defines the configuration for custom SSO providers with full OpenID Connect support. Includes detailed endpoint and attribute configurations. ```java record SsoClientConf(String clientId, String clientSecret, String authorizationUrl, String tokenUrl, String userInfoUrl, String scopes, String userNameAttribute, String issuerUri, String jwkSetUri) ``` -------------------------------- ### OAuth2 Proxy Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md Configure proxy settings for OAuth2 communication. Ensure the host, port, and authentication details are correctly set. ```yaml oauth2: proxy: enabled: true host: "proxy.example.com" port: 8080 username: "proxyuser" password: "proxypass" connect-timeout-millis: 10000 ``` -------------------------------- ### supports Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfileMapper.md Determines whether this mapper supports the given OAuth2 provider registration ID. This allows for selecting the correct mapper for a specific OAuth2 provider. ```APIDOC ## supports ### Description Determines whether this mapper supports the given OAuth2 provider registration ID. ### Method ```java boolean supports(String registrationId) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | registrationId | String | The OAuth2 provider registration identifier (e.g., "github", "gitlab") | ### Returns `boolean` - True if this mapper supports the registration ID, false otherwise ### Throws None ### Purpose Allows the mapper manager to select the appropriate mapper for a given provider. Mappers can be provider-specific (supporting only "github") or generic (supporting any provider). ``` -------------------------------- ### Configure OIDC ID Token Validation with JWS Algorithm Resolver Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2AuthenticationWebFilter.md Sets up a JWS algorithm resolver for OIDC ID token validation. It attempts to read supported algorithms from provider configuration and falls back to RS256 if detection fails or an error occurs. ```java var oidcIdTokenDecodeFactory = new ReactiveOidcIdTokenDecoderFactory(); oidcIdTokenDecodeFactory.setJwsAlgorithmResolver(clientRegistration -> { var configurationMetadata = clientRegistration.getProviderDetails() .getConfigurationMetadata(); try { var supportedJwsAlgorithms = JSONObjectUtils.getStringList( new JSONObject(configurationMetadata), "id_token_signing_alg_values_supported" ); if (!supportedJwsAlgorithms.isEmpty()) { return SignatureAlgorithm.from(supportedJwsAlgorithms.get(0)); } } catch (ParseException e) { // ignore } return SignatureAlgorithm.RS256; }); ``` -------------------------------- ### Configure Timeout for Client Removal Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/UserConnectionDisconnectedListener.md Configure the maximum time to wait for the removal of an authorized client. If the removal operation exceeds this duration, it will time out and be logged as a debug message. ```java .blockOptional(Duration.ofMinutes(1)) ``` -------------------------------- ### Convert to Halo AuthorizedClient Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/DefaultOAuth2AuthorizedClientService.md Converts Spring's OAuth2AuthorizedClient to Halo's AuthorizedClient extension. This process includes creating new metadata, extracting token information, converting scopes, and handling optional refresh tokens. ```java AuthorizedClient toAuthorizedClient(OAuth2AuthorizedClient param) ``` -------------------------------- ### OAuth2 Initializer Class Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2LoginConfiguration.md The inner Initializer class lazily creates all OAuth2 components. ```java class Initializer { ServerWebExchangeMatcher getAuthenticationMatcher() ReactiveClientRegistrationRepository getClientRegistrationRepository() ServerOAuth2AuthorizedClientRepository getAuthorizedClientRepository() ReactiveOAuth2AuthorizedClientService getAuthorizedClientService() } ``` -------------------------------- ### OAuth2 Login Request Flow Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/README.md Illustrates the sequence of HTTP requests and filter interactions during an OAuth2 login process, from user initiation to post-authentication redirection. ```text HTTP Request Flow: ┌─────────────────────────────────────────────────────────┐ │ 1. User initiates OAuth2 login │ /oauth2/authorization/{provider} └────────────────┬────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 2. HaloOAuth2RedirectWebFilter │ - Constructs authorization request │ - Redirects to provider └────────────────┬────────────────────────────────────────┘ │ ▼ (User authenticates at provider) ┌─────────────────────────────────────────────────────────┐ │ 3. Provider redirects with authorization code │ /login/oauth2/code/{provider}?code=...&state=... └────────────────┬────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 4. HaloOAuth2AuthenticationWebFilter │ - Exchanges code for access token │ - Fetches user information │ - Maps to Oauth2UserProfile └────────────────┬────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 5. DefaultOAuth2AuthorizedClientService │ - Stores tokens in AuthorizedClient extension │ - Creates security context └────────────────┬────────────────────────────────────────┘ │ ▼ (Post-authentication) ┌─────────────────────────────────────────────────────────┐ │ 6. User redirected to /uc (user center) │ - User is authenticated │ - OAuth2 tokens available for API calls └─────────────────────────────────────────────────────────┘ ``` -------------------------------- ### UserConnectionDisconnectedListener Constructor Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/UserConnectionDisconnectedListener.md Initializes the listener with the necessary Oauth2LoginConfiguration, which provides access to the authorized client service for managing credentials. ```java public UserConnectionDisconnectedListener(Oauth2LoginConfiguration configuration) ``` -------------------------------- ### OauthClientRegistrationRepository Class Overview Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md This snippet shows the basic structure of the OauthClientRegistrationRepository class, which implements Spring Security's ReactiveClientRegistrationRepository interface. It is designed to load OAuth2 provider configurations from Halo extensions. ```java @RequiredArgsConstructor public class OauthClientRegistrationRepository implements ReactiveClientRegistrationRepository ``` -------------------------------- ### Fetch Enabled OAuth2 Providers Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Retrieves the set of enabled provider registration IDs from system settings. Returns an empty set if no settings are found. ```java Mono> fetchEnabledProviders() ``` -------------------------------- ### HTTP Client Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/HaloOAuth2AuthenticationWebFilter.md Details the configuration of the HttpClient used by the OAuth2 filter, including timeouts and proxy support. ```APIDOC ## HTTP Client Configuration ### Description Configures the Reactor Netty `HttpClient` used for OAuth2 communication. ### Settings - **Default Connect Timeout:** 15 seconds - **Proxy Support:** Supports HTTP proxy with optional authentication. - **Custom Proxy Timeout:** The default timeout can be overridden using `connectTimeoutMillis`. ``` -------------------------------- ### Authenticated HTTP Proxy Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Use this configuration to route OAuth2 requests through an authenticated HTTP proxy. Provide the proxy host, port, username, and password for BASIC authentication. ```yaml oauth2: proxy: enabled: true host: "proxy.company.com" port: 8080 username: "services-user" password: "encrypted-password" ``` -------------------------------- ### Convert String to AuthenticationMethod Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthClientRegistrationRepository.md Converts a string representation to Spring's AuthenticationMethod. Defaults to AuthenticationMethod.HEADER if the string is not recognized. ```java AuthenticationMethod toAuthenticationMethod(String method) ``` -------------------------------- ### Add Additional Parameters with putIfAbsent Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/SocialServerOauth2AuthorizationRequestResolver.md Configures the OAuth2 authorization request builder to add query parameters using `putIfAbsent`. This ensures that existing OAuth2 parameters are not overwritten and that if a parameter exists in both query parameters and OAuth2 parameters, the OAuth2 parameter takes precedence. Only the first value of a parameter is used if duplicates exist. ```java builder.additionalParameters( params -> queryParams.forEach(params::putIfAbsent)); ``` -------------------------------- ### Internal Mapper Selection Algorithm Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/Oauth2UserProfileMapperManager.md This snippet illustrates the internal logic for selecting an Oauth2UserProfileMapper based on the registration ID. It retrieves, orders, and filters mappers from the Spring context, returning the first one that supports the given ID or throwing an exception if none is found. ```java applicationContext.getBeanProvider(Oauth2UserProfile.class) .orderedStream() .filter(mapper -> mapper.supports(registrationId)) .findFirst() .map(mapper -> mapper.mapProfile(oauth2User)) .orElseThrow(() -> new IllegalArgumentException( "No Oauth2UserProfileMapper found for registration id: " + registrationId)); ``` -------------------------------- ### onApplicationEvent Method for UserConnectionDisconnectedListener Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/UserConnectionDisconnectedListener.md Handles the UserConnectionDisconnectedEvent asynchronously. It extracts user connection details, removes OAuth2 authorized client credentials, and waits for up to 1 minute for the deletion to complete. Exceptions are logged. ```java @Override @Async public void onApplicationEvent(UserConnectionDisconnectedEvent event) ``` -------------------------------- ### Direct Connection (No Proxy) Configuration Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/configuration.md Use this configuration to disable the HTTP proxy, ensuring OAuth2 requests are sent directly to providers. ```yaml oauth2: proxy: enabled: false ``` -------------------------------- ### OAuth2 Client Registration Data Object Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/README.md Defines the structure for OAuth2 client registration, including metadata and specification details like token, authorization, and user info URIs. ```text Oauth2ClientRegistration (Extension) ├── Metadata: name = provider ID (github, gitlab, etc.) └── Spec: Oauth2ClientRegistrationSpec ├── tokenUri (required) ├── authorizationUri ├── userInfoUri ├── scopes └── ...other config ``` -------------------------------- ### OauthGithubPlugin Class Definition Source: https://github.com/halo-sigs/plugin-oauth2/blob/main/_autodocs/api-reference/OauthGithubPlugin.md Defines the OauthGithubPlugin class, extending Spring Halo's BasePlugin to manage OAuth2 extensions. ```java public class OauthGithubPlugin extends BasePlugin ```