<%#
 Copyright 2013-2024 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
package <%= packageName %>.config;

import <%= packageName %>.security.*;
import tech.jhipster.config.JHipsterProperties;

<%_ if (authenticationTypeSession || devDatabaseTypeH2Any) { _%>
  <%_ if (javaVersion === '8') { _%>
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
  <%_ } else { _%>
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
  <%_ } _%>

<%_ } _%>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
<%_ if (devDatabaseTypeH2Any) { _%>
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import tech.jhipster.config.JHipsterConstants;
<%_ } _%>
<%_ if (authenticationTypeJwt) { _%>
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
<%_ } _%>
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
<%_ if (!skipClient) { _%>
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
<%_ } _%>
import org.springframework.security.web.SecurityFilterChain;
<%_ if (!skipClient || authenticationUsesCsrf) { _%>
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
<%_ } _%>
<%_ if (authenticationUsesCsrf) { _%>
import tech.jhipster.web.filter.CookieCsrfFilter;
<%_ } _%>
<%_ if (!skipClient) { _%>
import <%= packageName %>.web.filter.SpaWebFilter;
<%_ } _%>
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
<%_ } _%>
<%_ if (authenticationTypeJwt || (authenticationTypeOauth2 && applicationTypeMicroservice)) { _%>
import org.springframework.security.config.http.SessionCreationPolicy;
<%_ } _%>
<%_ if (generateUserManagement) { _%>
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
<%_ } _%>
<%_ if (authenticationTypeOauth2) { _%>
import static org.springframework.security.oauth2.core.oidc.StandardClaimNames.PREFERRED_USERNAME;

import <%= packageName %>.security.oauth2.AudienceValidator;
import <%= packageName %>.security.SecurityUtils;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.jwt.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
  <%_ if (!applicationTypeMicroservice) { _%>
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
  <%_ } _%>
import java.util.*;
<%_ } _%>
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
import java.util.function.Supplier;
<%_ } _%>
<%_ if (authenticationTypeSession) { _%>
import org.springframework.http.HttpStatus;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
  <%_ if (generateUserManagement) { _%>
import org.springframework.security.web.authentication.RememberMeServices;
  <%_ } _%>
<%_ } _%>
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
import org.springframework.security.web.csrf.*;
<%_ } _%>
<%_ if (authenticationTypeJwt) { _%>
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
<%_ } _%>
<%_ if (authenticationTypeOauth2 && !applicationTypeMicroservice) { _%>
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.boot.web.client.RestTemplateBuilder;
import <%= packageName %>.security.oauth2.CustomClaimConverter;
<%_ } _%>
<%_ if(!skipClient) { _%>
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
<%_ } _%>
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
import org.springframework.util.StringUtils;
<%_ } _%>
<%# add by begcode start %>
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
<%_
  const requestMatchers = javaVersion === '17' ? 'requestMatchers' : 'antMatchers';
_%>
<%_ if (devDatabaseTypeH2Any && javaVersion === '8') { _%>
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
<%_ } _%>
<%# add by begcode end %>
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;

<%_ if (authenticationTypeOauth2 || !applicationTypeMicroservice || authenticationTypeJwt) { _%>
import static org.springframework.security.config.Customizer.withDefaults;
<%_ } _%>

@Configuration
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfiguration {
<%_ if (devDatabaseTypeH2Any) { _%>

    private final Environment env;
<%_ } _%>

    private final JHipsterProperties jHipsterProperties;
<%_ if (authenticationTypeSession && generateUserManagement) { _%>

    private final RememberMeServices rememberMeServices;
<%_ } _%>
<%_ if (authenticationTypeOauth2) { _%>

    @Value("${spring.security.oauth2.client.provider.oidc.issuer-uri}")
    private String issuerUri;
    <%_ } _%>
<%_ if (applicationTypeMonolith && authenticationTypeJwt) { _%>

    private final AccessSecurityMetadataSource accessSecurityMetadataSource;

    private final AccessDecisionManagerImpl accessDecisionManagerImpl;
<%_ } _%>

    public SecurityConfiguration(<% if (devDatabaseTypeH2Any) { %>Environment env, <% } %><% if (authenticationTypeSession && generateUserManagement) { %>RememberMeServices rememberMeServices, <% } %> JHipsterProperties jHipsterProperties<% if (applicationTypeMonolith && authenticationTypeJwt) { %>, AccessSecurityMetadataSource accessSecurityMetadataSource, AccessDecisionManagerImpl accessDecisionManagerImpl<% } %>) {<%# modify by begcode %>
<%_ if (devDatabaseTypeH2Any) { _%>
        this.env = env;
<%_ } _%>
<%_ if (authenticationTypeSession && generateUserManagement) { _%>
        this.rememberMeServices = rememberMeServices;
<%_ } _%>
        this.jHipsterProperties = jHipsterProperties;
<%_ if (applicationTypeMonolith && authenticationTypeJwt) { _%>
        this.accessSecurityMetadataSource = accessSecurityMetadataSource;
        this.accessDecisionManagerImpl = accessDecisionManagerImpl;
<%_ } _%>
    }
<%_ if (generateUserManagement) { _%>

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
<%_ } _%>

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http<% if (javaVersion !== '8') { %>, MvcRequestMatcher.Builder mvc<% } %>) throws Exception {
        http
<%_ if (!applicationTypeMicroservice) { _%>
            .cors(withDefaults())
<%_ } _%>
            .csrf(csrf -> csrf
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .csrfTokenRequestHandler(new SpaCsrfTokenRequestHandler()))
<%_ } else { _%>
                .disable())
<%_ } _%>
<%_ if (!skipClient) { _%>
            .addFilterAfter(new SpaWebFilter(), BasicAuthenticationFilter.class)
<%_ } _%>
            <%_ if (applicationTypeMonolith && authenticationTypeJwt) { _%><%# add by begcode %>
            .addFilterAt(new AccessSecurityInterceptor(accessSecurityMetadataSource, accessDecisionManagerImpl), FilterSecurityInterceptor.class)
            <%_ } _%>
<%_ if (!applicationTypeMicroservice) { _%>
  <%_ if (authenticationUsesCsrf) { _%>
            .addFilterAfter(new CookieCsrfFilter(), BasicAuthenticationFilter.class)
  <%_ } _%>
<%_ } _%>
<%_ if (!skipClient) { _%>
            .headers(headers -> headers
                .contentSecurityPolicy(csp -> csp.policyDirectives(jHipsterProperties.getSecurity().getContentSecurityPolicy()))
                .frameOptions(FrameOptionsConfig::sameOrigin)
                .referrerPolicy(referrer -> referrer.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))
                .permissionsPolicy(permissions ->
                    permissions.policy("camera=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=()")))
<%_ } _%>
            .authorizeHttpRequests(authz ->
                // prettier-ignore
                authz
<%_ if (!skipClient) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/index.html","/*.js","/*.txt","/*.json","/*.map","/*.css"<% } else { %>mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/*.ico","/*.png","/*.svg","/*.webapp"<% } else { %>mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")<% } %>).permitAll()
  <%_ if (clientFrameworkVue) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/assets/**"<% } else { %>mvc.pattern("/assets/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/avatar/**"<% } else { %>mvc.pattern("/avatar/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/js/**"<% } else { %>mvc.pattern("/js/**")<% } %>).permitAll()
    <%_ if (microfrontend) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/app/**"<% } else { %>mvc.pattern("/app/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/i18n/**"<% } else { %>mvc.pattern("/i18n/**")<% } %>).permitAll()
    <%_ } _%>
  <%_ } else { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/app/**"<% } else { %>mvc.pattern("/app/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/i18n/**"<% } else { %>mvc.pattern("/i18n/**")<% } %>).permitAll()
  <%_ } _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/content/**"<% } else { %>mvc.pattern("/content/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/swagger-ui/**"<% } else { %>mvc.pattern("/swagger-ui/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/upload/**"<% } else { %>mvc.pattern("/upload/**")<% } %>).permitAll()
<%_ } _%>
<%_ if (authenticationTypeJwt) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>HttpMethod.POST, "/api/authenticate"<% } else { %>mvc.pattern(HttpMethod.POST, "/api/authenticate")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>HttpMethod.GET, "/api/authenticate"<% } else { %>mvc.pattern(HttpMethod.GET, "/api/authenticate")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/authenticate/withoutCaptcha"<% } else { %>mvc.pattern("/api/authenticate/withoutCaptcha")<% } %>).permitAll()<%# add by begcode start %>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/authenticate/mobile"<% } else { %>mvc.pattern("/api/authenticate/mobile")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/mobile/smscode"<% } else { %>mvc.pattern("/api/mobile/smscode")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/users/check"<% } else { %>mvc.pattern("/api/users/check")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/mobile/reset-password/smscode"<% } else { %>mvc.pattern("/api/mobile/reset-password/smscode")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/oauth/**"<% } else { %>mvc.pattern("/api/oauth/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/*/public"<% } else { %>mvc.pattern("/api/*/public")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/*/public/*"<% } else { %>mvc.pattern("/api/*/public/*")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/randomImage/**"<% } else { %>mvc.pattern("/api/randomImage/**")<% } %>).permitAll()<%# add by begcode end %>
<%_ } else { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/authenticate"<% } else { %>mvc.pattern("/api/authenticate")<% } %>).permitAll()
<%_ } _%>
<%_ if (generateUserManagement) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/register"<% } else { %>mvc.pattern("/api/register")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/activate"<% } else { %>mvc.pattern("/api/activate")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/account/reset-password/init"<% } else { %>mvc.pattern("/api/account/reset-password/init")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/account/reset-password/finish"<% } else { %>mvc.pattern("/api/account/reset-password/finish")<% } %>).permitAll()
<%_ } _%>
                    // jhipster-needle-add-authorize-http-request
<%_ if (authenticationTypeOauth2) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/auth-info"<% } else { %>mvc.pattern("/api/auth-info")<% } %>).permitAll()
<%_ } _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/admin/**"<% } else { %>mvc.pattern("/api/admin/**")<% } %>).hasAuthority(AuthoritiesConstants.ADMIN)
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/api/**"<% } else { %>mvc.pattern("/api/**")<% } %>).authenticated()
<%_ if (applicationTypeGateway) { _%>
  <%_ if (microfrontend) { _%>
                    // microfrontend resources are loaded by webpack without authentication, they need to be public
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/*.js"<% } else { %>mvc.pattern("/services/*/*.js")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/*.txt"<% } else { %>mvc.pattern("/services/*/*.txt")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/*.json"<% } else { %>mvc.pattern("/services/*/*.json")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/*.js.map"<% } else { %>mvc.pattern("/services/*/*.js.map")<% } %>).permitAll()
  <%_ } _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/management/health/readiness"<% } else { %>mvc.pattern("/services/*/management/health/readiness")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/*/v3/api-docs"<% } else { %>mvc.pattern("/services/*/v3/api-docs")<% } %>).hasAuthority(AuthoritiesConstants.ADMIN)
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/services/**"<% } else { %>mvc.pattern("/services/**")<% } %>).authenticated()
<%_ } _%>
<%_ if (communicationSpringWebsocket) { _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/websocket/**"<% } else { %>mvc.pattern("/websocket/**")<% } %>).authenticated()
<%_ } _%>
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/v3/api-docs/**"<% } else { %>mvc.pattern("/v3/api-docs/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/management/health"<% } else { %>mvc.pattern("/management/health")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/management/health/**"<% } else { %>mvc.pattern("/management/health/**")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/management/info"<% } else { %>mvc.pattern("/management/info")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/management/prometheus"<% } else { %>mvc.pattern("/management/prometheus")<% } %>).permitAll()
                    .<%= requestMatchers %>(<% if (javaVersion === '8') { %>"/management/**"<% } else { %>mvc.pattern("/management/**")<% } %>).permitAll()
                )
<%_ if (authenticationTypeSession) { _%>
  <%_ if (generateUserManagement) { _%>
            .rememberMe(rememberMe ->
                rememberMe
                    .rememberMeServices(rememberMeServices)
                    .rememberMeParameter("remember-me")
                    .key(jHipsterProperties.getSecurity().getRememberMe().getKey())
            )
  <%_ } _%>
            .exceptionHandling(exceptionHanding ->
                exceptionHanding.defaultAuthenticationEntryPointFor(
                    new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
                    new OrRequestMatcher(
  <%_ if (communicationSpringWebsocket) { _%>
                        antMatcher("/websocket/**"),
  <%_ } _%>
                        antMatcher("/api/**")
                    )
                )
            )
            .formLogin(formLogin ->
                formLogin
                    .loginPage("/")
                    .loginProcessingUrl("/api/authentication")
                    .successHandler((request, response, authentication) -> response.setStatus(HttpStatus.OK.value()))
                    .failureHandler((request, response, exception) -> response.setStatus(HttpStatus.UNAUTHORIZED.value()))
                    .permitAll()
            )
            .logout(logout ->
                logout.logoutUrl("/api/logout").logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()).permitAll());
<%_ } else if (authenticationTypeJwt) { _%>
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .exceptionHandling((exceptions) -> exceptions
				.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
				.accessDeniedHandler(new BearerTokenAccessDeniedHandler()))
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults()));
<%_ } else if (authenticationTypeOauth2) { _%>
  <%_ if (!applicationTypeMicroservice) { _%>
            .oauth2Login(oauth2 -> oauth2.loginPage("/").userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService())))
  <%_ } else { _%>
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
  <%_ } _%>
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults()))
            .oauth2Client(withDefaults());
<%_ } _%>
<%_ if (devDatabaseTypeH2Any) { _%>
        if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) {
            http
  <%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>
                .csrf(csrf -> csrf.ignoringRequestMatchers(<% if (javaVersion === '8') { %>new AntPathRequestMatcher<% } else { %>antMatcher<% } %>("/h2-console/**")))
  <%_ } _%>
                .authorizeHttpRequests(authz -> authz.requestMatchers(<% if (javaVersion === '8') { %>new AntPathRequestMatcher<% } else { %>antMatcher<% } %>("/h2-console/**")).permitAll());
        }
<%_ } _%>
        return http.build();
    }
<%_ if (javaVersion !== '8') { _%>

    @Bean
    MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
        return new MvcRequestMatcher.Builder(introspector);
    }
<%_ } _%>
<%_ if (authenticationTypeOauth2) { _%>

    OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
        final OidcUserService delegate = new OidcUserService();

        return userRequest -> {
            OidcUser oidcUser = delegate.loadUser(userRequest);
            return new DefaultOidcUser(oidcUser.getAuthorities(), oidcUser.getIdToken(), oidcUser.getUserInfo(), PREFERRED_USERNAME);
        };
    }
  <%_ if (!applicationTypeMicroservice) { _%>

    /**
     * Map authorities from "groups" or "roles" claim in ID Token.
     *
     * @return a {@link GrantedAuthoritiesMapper} that maps groups from
     * the IdP to Spring Security Authorities.
     */
    @Bean
    public GrantedAuthoritiesMapper userAuthoritiesMapper() {
        return (authorities) -> {
            Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

            authorities.forEach(authority -> {
                // Check for OidcUserAuthority because Spring Security 5.2 returns
                // each scope as a GrantedAuthority, which we don't care about.
                if (authority instanceof OidcUserAuthority) {
                    OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;
                    mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims()));
                }
            });
            return mappedAuthorities;
        };
    }
  <%_ } _%>

    @Bean
    JwtDecoder jwtDecoder(<%_ if (!applicationTypeMicroservice) { _%>ClientRegistrationRepository clientRegistrationRepository, RestTemplateBuilder restTemplateBuilder<%_ } _%>) {
        NimbusJwtDecoder jwtDecoder = JwtDecoders.fromOidcIssuerLocation(issuerUri);

        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(jHipsterProperties.getSecurity().getOauth2().getAudience());
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

        jwtDecoder.setJwtValidator(withAudience);
  <%_ if (!applicationTypeMicroservice) { _%>
        jwtDecoder.setClaimSetConverter(new CustomClaimConverter(clientRegistrationRepository.findByRegistrationId("oidc"), restTemplateBuilder.build()));
  <%_ } _%>

        return jwtDecoder;
    }
<%_ } _%>
<%_ if (authenticationUsesCsrf && !applicationTypeMicroservice) { _%>

    /**
     * Custom CSRF handler to provide BREACH protection.
     *
     * @see <a href="https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#csrf-integration-javascript-spa">Spring Security Documentation - Integrating with CSRF Protection</a>
     * @see <a href="https://github.com/jhipster/generator-jhipster/pull/25907">JHipster - use customized SpaCsrfTokenRequestHandler to handle CSRF token</a>
     * @see <a href="https://stackoverflow.com/q/74447118/65681">CSRF protection not working with Spring Security 6</a>
     */
    static final class SpaCsrfTokenRequestHandler extends CsrfTokenRequestAttributeHandler {
        private final CsrfTokenRequestHandler delegate = new XorCsrfTokenRequestAttributeHandler();

        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response, Supplier<CsrfToken> csrfToken) {
            /*
             * Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection of
             * the CsrfToken when it is rendered in the response body.
             */
            this.delegate.handle(request, response, csrfToken);
        }

        @Override
        public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) {
            /*
             * If the request contains a request header, use CsrfTokenRequestAttributeHandler
             * to resolve the CsrfToken. This applies when a single-page application includes
             * the header value automatically, which was obtained via a cookie containing the
             * raw CsrfToken.
             */
            if (StringUtils.hasText(request.getHeader(csrfToken.getHeaderName()))) {
                return super.resolveCsrfTokenValue(request, csrfToken);
            }
            /*
             * In all other cases (e.g. if the request contains a request parameter), use
             * XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies
             * when a server-side rendered form includes the _csrf request parameter as a
             * hidden input.
             */
            return this.delegate.resolveCsrfTokenValue(request, csrfToken);
        }
    }
<%_ } _%>
}
