I have a spring Boot application which is protected by spring authorization server. In addition, the frontend of my application is Angular.
I want when a user who is not authenticated and wants to access a resource, he will be directed to the login page first, and after successful authentication, he will be returned to the same resource he requested.
Now the first part of the work works correctly, that is, the user is directed to the login page, but after successful authentication, when I want to return the user to the address page that he requested before authentication, my program does not work. That is, in my code
var savedReq = new HttpSessionRequestCache().getRequest(req, res);
The savedReq variable is always null.
My second question is that I somehow store the requested url of the user with non-standard methods and send it to the Angular program after authentication, but when I want to refer to that address, it redirects me to the login page. This is if the user is authenticated once.
Next, I will share my source code for you to see. Sorry that my questions are long. Thank you very much for your help and guidance.
@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Bean
@Order(1)
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
http
.cors(Customizer.withDefaults())
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("http://localhost:4201/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
@Bean
@Order(2)
SecurityFilterChain authenticationSecurityFilterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/login", "/logout")
.cors(Customizer.withDefaults())
.csrf((csrf) -> csrf.disable())
.formLogin(form -> form
.loginPage("http://localhost:4201/login")
.loginProcessingUrl("/login")
.successHandler((req, res, auth) -> {
res.resetBuffer();
res.setStatus(HttpStatus.OK.value());
res.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
var savedReq = new HttpSessionRequestCache().getRequest(req, res);
res.getWriter()
.append("{"redirectUrl": "")
.append(savedReq == null ? "" : savedReq.getRedirectUrl())
.append(""}");
res.flushBuffer();
})
.failureHandler((req, res, ex) -> res.setStatus(HttpStatus.UNAUTHORIZED.value()))
)
.logout(logout -> logout
.logoutSuccessUrl("https://localhost:4201/login?logout")
)
.exceptionHandling(handler -> handler
.authenticationEntryPoint(
new HttpStatusEntryPoint(HttpStatus.FORBIDDEN)
)
)
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
);
return http.build();
}
@Bean
@Order(3)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.cors(Customizer.withDefaults())
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
);
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return source;
}
}