I'm trying to set up an authorization server using spring-boot-starter-oauth2-authorization-server. The thing is that when I try to enter my login and password, an error occurs "No AuthenticationProvider found". Please help me fix this.
SecurityConfig class
@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class SecurityConfig {
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize ->
authorize.anyRequest().authenticated())
.csrf(AbstractHttpConfigurer::disable);
return http.formLogin(Customizer.withDefaults()).build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username("admin")
.password("{noop}password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
AuthorizationServerConfig class
@Configuration
@RequiredArgsConstructor
public class AuthorizationServerConfig {
private final OAuth2AuthorizationServerProperties authorizationServerProperties;
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.exceptionHandling(exception ->
exception.authenticationEntryPoint(
new LoginUrlAuthenticationEntryPoint("/login")));
return http.build();
}
@Bean
public RegisteredClientRepository registeredClientRepository() {
return new InMemoryRegisteredClientRepository(
RegisteredClient.withId("test-client-id")
.clientName("Test Client")
.clientId("test-client")
.clientSecret("{noop}test-client")
.redirectUri("http://localhost:5000/code")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.build()
);
}
@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 ((jwkSelector, securityContext) -> jwkSelector.select(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()
.issuer(authorizationServerProperties.getIssuer())
.build();
}
}
application.yaml
server:
port: 7777
logging:
level:
org:
springframework:
security: trace
spring:
application:
name: j-sso
security:
oauth2:
authorizationserver:
issuer-url: http://localhost:7777
trace log
2024-11-13T01:03:51.717+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-6] o.s.s.w.s.HttpSessionRequestCache : Did not save request since it did not match [And [Ant [pattern='/**', GET], Not [Ant [pattern='/**/favicon.*']], Not [MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@1858a268, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]], Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@1858a268, matchingMediaTypes=[multipart/form-data], useEquals=false, ignoredMediaTypes=[*/*]]], Not [MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@1858a268, matchingMediaTypes=[text/event-stream], useEquals=false, ignoredMediaTypes=[*/*]]]]]
2024-11-13T01:03:51.717+03:00 DEBUG 3596 --- [j-sso] [nio-7777-exec-6] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@1858a268, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2024-11-13T01:03:51.718+03:00 DEBUG 3596 --- [j-sso] [nio-7777-exec-6] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@2fd72332
2024-11-13T01:03:51.718+03:00 DEBUG 3596 --- [j-sso] [nio-7777-exec-6] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:7777/login
2024-11-13T01:03:51.718+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-6] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
2024-11-13T01:03:51.732+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@9fdc290, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1fc0cdb4, org.springframework.security.web.context.SecurityContextHolderFilter@7793ad58, org.springframework.security.web.header.HeaderWriterFilter@62765aec, org.springframework.security.web.csrf.CsrfFilter@5dfe23e8, org.springframework.security.web.authentication.logout.LogoutFilter@5af64ce0, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@49f3ff41, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4207852d, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@733e2d75, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@4f2d014a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@16132f21, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4640195a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2a4db2b5, org.springframework.security.web.access.ExceptionTranslationFilter@50b0afd7, org.springframework.security.web.access.intercept.AuthorizationFilter@56846330]] (1/1)
2024-11-13T01:03:51.733+03:00 DEBUG 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Securing GET /login
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking DisableEncodeUrlFilter (1/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (2/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderFilter (3/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (4/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking CsrfFilter (5/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.csrf.CsrfFilter : Did not protect against CSRF since request did not match CsrfNotRequired [TRACE, HEAD, GET, OPTIONS]
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (6/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.s.w.a.logout.LogoutFilter : Did not match request to Ant [pattern='/logout', POST]
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking UsernamePasswordAuthenticationFilter (7/15)
2024-11-13T01:03:51.733+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]
2024-11-13T01:03:51.734+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.security.web.FilterChainProxy : Invoking DefaultLoginPageGeneratingFilter (8/15)
2024-11-13T01:03:51.734+03:00 TRACE 3596 --- [j-sso] [nio-7777-exec-7] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
Error enter image description here
I tried to set up mine like this https://wankhedeshubham.medium.com/spring-boot-security-with-userdetailsservice-and-custom-authentication-provider-3df3a188993f but it didn't help me.
Link to github repo: https://github.com/HaHhaRr/AuthServer
After looking at the Github, the main reason for your initial error is that the class marked with @SpringBootApplication
is inside another package as the rest of the configuration classes.
By default, Spring Boot scans for packages starting with the package that the @SpringBootApplication annotated class is in, and also sub-packages in that folder. The app isn't aware of the classes in com.haharr.security
package.
And that is also the reason why it works when you define UserDetailsService inside the Main class annotated with @SpringBootApplication
. The rest of classes in other packages are in fact ignored and the app works thanks to autoconfigurations.
Although the app can be configured to look for components in other places, I strongly suggest to follow the best practices and move the AuthorizationServerApplication
one package (folder) up, in com.haharr
pacakage (from com.haharr.authorizationserver
package).
After that, another whole set of problems to be solved, but that is food for another thread and most likely the tutorials can help with them.