I made a OAuth2 server with spring boot 3.x + spring-security-oauht2-authorization-server-1.22
public SecurityConfiguration( AuthService authService ) {
this.authService = authService;
}
@Bean
@Order( 1 )
public SecurityFilterChain authorizationServerSecurityFilterChain( HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer( OAuth2AuthorizationServerConfigurer.class)
.oidc( Customizer.withDefaults() )
;
//// .authorizationEndpoint( Customizer.withDefaults() )
//// .tokenGenerator(
//// new OAuth2TokenGenerator< OAuth2Token >() {
//// @Override
//// public OAuth2Token generate( OAuth2TokenContext context ) {
////
//// Instant now = Instant.now();
////
//// long accessLive = context.getRegisteredClient().getTokenSettings().getAccessTokenTimeToLive().toSeconds();
//// long refreshLive = context.getRegisteredClient().getTokenSettings().getRefreshTokenTimeToLive().toSeconds();
////
//// if( context.getTokenType() == OAuth2TokenType.ACCESS_TOKEN )
//// return new OAuth2AccessToken( OAuth2AccessToken.TokenType.BEARER, UUID.randomUUID().toString(),now, now.plusSeconds( accessLive ));
//// else if( context.getTokenType() == OAuth2TokenType.REFRESH_TOKEN)
//// return new OAuth2RefreshToken( UUID.randomUUID().toString(), now, now.plusSeconds( refreshLive ) );
//// else {
////
//// JwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource());
//// JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
////
//// return jwtGenerator.generate( context );
//// }
////
//// }
////
//// }
//// )
//// .authorizationEndpoint( a -> a.authorizationResponseHandler( new AuthenticationSuccessHandler() {
//// @Override
//// public void onAuthenticationSuccess( HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException {
//// System.out.println("ddddd");
//// }
//// } ) )
// ;
//
////
// http.exceptionHandling(exceptions -> exceptions
// .defaultAuthenticationEntryPointFor(
// new LoginUrlAuthenticationEntryPoint( "/login" ),
// new MediaTypeRequestMatcher( MediaType.TEXT_HTML)
// ));
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests( requests -> requests.anyRequest().permitAll())
.csrf( httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.disable())
.cors( httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.disable() )
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin( Customizer.withDefaults() );
;
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username( "user" )
.password( "user" )
.roles( "USER" )
.build();
return new InMemoryUserDetailsManager( userDetails );
}
// @Bean AuthorizationFilter authorizationFilter( ){
//
// return new AuthorizationFilter( new AuthorizationManager< HttpServletRequest >() {
// @Override
// public AuthorizationDecision check( Supplier< Authentication > authentication, HttpServletRequest object ) {
//
// System.out.println("dhdhiahsdfoihasdofhjadsofasdfasdfasdfasdfasdfasdfasdf");
// return new AuthorizationDecision( true );
// }
// } );
// }
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient oidcClient = RegisteredClient.withId( UUID.randomUUID().toString())
.clientId("client")
.clientSecret("{noop}secret")
.scope( OidcScopes.OPENID )
.scope( OidcScopes.PROFILE )
// .clientAuthenticationMethod( ClientAuthenticationMethod.CLIENT_SECRET_JWT )
.clientAuthenticationMethod( ClientAuthenticationMethod.CLIENT_SECRET_POST )
.clientAuthenticationMethod( ClientAuthenticationMethod.NONE )
.authorizationGrantType( AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
// .redirectUri( "http://localhost:8000/login" )
.redirectUri( UI_LOCAL_URL )
// .postLogoutRedirectUri("http://localhost:8002/")
// .tokenSettings( TokenSettings.builder()
// .accessTokenTimeToLive( Duration.ofSeconds( 3600 ) )
// .refreshTokenTimeToLive( Duration.ofDays( 1 ) )
// .build() )
// .clientSettings( ClientSettings.builder()
// .requireAuthorizationConsent(true)
// .build())
.build();
return new InMemoryRegisteredClientRepository(oidcClient);
}
@Bean
public JWKSource< SecurityContext > jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAKey rsaKey = new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
@Bean
public JwtDecoder jwtDecoder( JWKSource< SecurityContext > jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().build();
}
And then I called http://localhost:8002/oauth2/authorize?response_type=code&client_id=client&scpoe=openid&redirect_uri=http://localhost:3000/login.
I expected my auth server redirect to given url. but it doesn't work. they give 401 error.
So I debug my code.
and when authorization filter works, authorization filter made a authorization decision (isGranted =false).
I think this made a 401 error. but I didn't have idea...
please let me know how to fix it...!
and here is debug log
[2024-03-18 11:32:06.079][http-nio-8002-exec-1] DEBUG [org.springframework.security.web.authentication.AnonymousAuthenticationFilter.defaultWithAnonymous:119] - Set SecurityContextHolder to anonymous SecurityContext
[2024-03-18 11:32:06.087][http-nio-8002-exec-1] DEBUG [org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest:80] - Saved request http://localhost:8002/oauth2/authorize?response_type=code&client_id=client&scpoe=openid&redirect_uri=http://localhost:3000/login&continue to session