Failed to bind properties clientid to OAuth2ClientProperties$Registration - spring-boot

I am working on a spring boot app in order to communicate with another secured API.
For that, I implement a OAuth2RestTemplate with the following properties but it failed when I run the application.
#Configuration
#EnableOAuth2Client
class RestTemplateConfiguration {
#Bean
#ConfigurationProperties("oauth2")
public OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails() {
return new ClientCredentialsResourceDetails();
}
#Bean
public OAuth2RestTemplate oAuth2RestTemplate(
#Qualifier("oAuth2ProtectedResourceDetails") OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails) {
return new OAuth2RestTemplate(oAuth2ProtectedResourceDetails);
}
}
application.properties
spring:
security:
oauth2:
client:
registration:
clientId: xxxxxxxxxxxxxxxxxx
clientSecret: xxxxxxxxxxxxxxxxx
accessTokenUri: https://xxxxxx/oauth2/access_token
scope: openid profile xxxxxxxxxxx
authorizationGrantType: client_credentials
The exception I get when I run the code
Failed to bind properties under 'spring.security.oauth2.client.registration.clientid' to org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties$Registration:

I think the problem is here
security:
oauth2:
client:
registration:
mb:
client-name: mb
client-id: ui
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri: http:localhost:8084/ui/login/oauth2/code/
scope: openId
client-authentication-method: basic
provider:
mb:
token-uri: http://localhost:8181/oauth/token
authorization-uri: http:localhost:8181/oauth/authorize
user-info-uri: http:localhost:8181/oauth/userinfo
user-name-attribute: name

I ran into the same issue. The reference documentation mentions that you need to provide a registrationId within the property "path"
You application.properties should look like this:
spring:
security:
oauth2:
client:
registration:
YOUR_REGISTRATION_ID: # <----------
clientId: xxxxxxxxxxxxxxxxxx
clientSecret: xxxxxxxxxxxxxxxxx
accessTokenUri: https://xxxxxx/oauth2/access_token
scope: openid profile xxxxxxxxxxx
authorizationGrantType: client_credentials

Related

Spring Oauth2 Login not working after migrating to Spring Boot 3

After migration to Spring Boot 3 from 2.7.5, when trying to login and get into infinity loop in the login screen.
After debugging we found this exception:
org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_request] client_secret is must in DefaultAuthorizationCodeTokenResponseClient.getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest)
You can check our how is defined our SecurityFilter chain.
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(new CsrfIgnoreRequestMatcher())
)
.headers(headers -> headers
.cacheControl().disable()
.frameOptions().disable()
)
//Access configuration
.authorizeHttpRequests(authorizeRequest -> authorizeRequest
.requestMatchers(HttpMethod.OPTIONS).permitAll()
.requestMatchers(
LOGIN,
LOGOUT).permitAll()
)
.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(new Http401UnauthorizedEntryPoint())
)
//######## OAUTH2-Login configuration ########
.oauth2Login(oAuth2Login -> oAuth2Login
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint
.baseUri(LOGIN)
.authorizationRequestResolver(customOAuth2AuthorizationRequestResolver)
)
.loginProcessingUrl(LOGIN)
.userInfoEndpoint(userInfo -> userInfo.userAuthoritiesMapper(new RoleMapper()))
)
.logout(logout -> logout
.logoutUrl(LOGOUT)
.invalidateHttpSession(true)
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
);
return http.build();
}
Here are our application.yaml properties for the security:
spring:
security:
oauth2:
client:
provider:
customIdp:
authorization-uri: https://sso.company/app/login
jwk-set-uri: https://sso.company/oauth/nam/keys
token-uri: https://sso.company/oauth/nam/token?resourceServer=IdentityProviderRSUE&
user-info-uri: https://sso.company/oauth/nam/userinfo
user-name-attribute: cn
customIdpSso:
authorization-uri: https://sso.company/app/login
token-uri: ${spring.security.oauth2.client.provider.customIdp.tokenUri}
user-info-uri: ${spring.security.oauth2.client.provider.customIdp.userInfoUri}
user-name-attribute: ${spring.security.oauth2.client.provider.customIdp.userNameAttribute}
registration:
customIdp:
authorizationGrantType: authorization_code
clientAuthenticationMethod: basic
client-id: custom-client-id
clientName: Custom
client-secret: custom-client-secret
provider: customIdp
redirect-uri: "{baseUrl}/api/login"
scope: portal
customIdpSso:
authorizationGrantType: ${spring.security.oauth2.client.registration.customIdp.authorizationGrantType}
clientAuthenticationMethod: ${spring.security.oauth2.client.registration.customIdp.clientAuthenticationMethod}
clientId: ${spring.security.oauth2.client.registration.customIdp.clientId}
clientName: ${spring.security.oauth2.client.registration.customIdp.clientName}
client-secret: ${spring.security.oauth2.client.registration.customIdp.clientSecret}
provider: customIdpnosso
redirect-uri: ${spring.security.oauth2.client.registration.customIdp.redirect-uri}
scope: ${spring.security.oauth2.client.registration.customIdp.scope}
We migrated to new Spring Boot version and stoped using WebSecurityConfigurerAdapter.
If you need more information please tell us.
Due to https://docs.spring.io/spring-security/reference/5.8/migration/servlet/oauth2.html#_clientauthenticationmethod, the value for clientAuthenticationMethod should now be:
clientAuthenticationMethod: client_secret_basic
UPDATE: I've created https://github.com/spring-projects/spring-security/issues/12585 to look into making this clearer.

Spring Boot, OAuth2 with azure and another provider (e.g. google)

I have an application that is using Azure Active directory to authenticate and I need to add another provider, for example google.
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends AadWebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.anyRequest().authenticated();
}
}
spring:
cloud:
azure:
active-directory:
enabled: true
profile:
tenant-id:
# credential:
client-id:
client-secret:
security:
oauth2:
client:
registration:
google:
client-id:
client-secret:
Using above code will force azure login.
How can I adapt the code to have both options azure and google?
I did not manage to make it work with spring-cloud-azure-starter-active-directory, so I removed this plugin and used:
spring:
security:
oauth2:
client:
registration:
google:
client-id:
client-secret:
azure:
client-id:
client-secret:
scope:
- openid
- profile
- email
authorization-grant-type: authorization_code
redirect-uri: http://localhost:8080/login/oauth2/code/azure
provider: azure-active-directory
provider:
azure-active-directory:
issuer-uri: https://login.microsoftonline.com/{tenant-id}/v2.0
This example helped me https://github.com/Azure-Samples/azure-spring-boot-samples/blob/spring-cloud-azure_v4.4.1/aad/spring-security/servlet/oauth2/login/src/main/resources/application.yml

spring boot Oauth Okta 404 on redirect

My Spring Boot app giving me an error as 404 after redirecting from the Okta server.
May I have some help to solve this. My configurations are as below.
This is my Okta server redirect
https://dev-40483106.okta.com/oauth2/default/v1/authorize?response_type=code&client_id=0oa3p7a86ycJ7olpP5d7&scope=openid%20email&state=xVpkZIPGaGqAQCZIMXZgTrbmKmHJbcKbtM95KO9RwVU%3D&redirect_uri=http://localhost:8082/mms-sso/auth&nonce=cPdNAYT4tQ9mAjhj4HUiynBEQVAnJHnBTIezqquOpJM
This is my Redirect URI where I am getting a 404 error
http://localhost:8082/mms-sso/auth?code=rOh9u2fwBTB7gasIMUgtjIDMs5_Sydqz-0O_jG5Qhj0&state=xVpkZIPGaGqAQCZIMXZgTrbmKmHJbcKbtM95KO9RwVU%3D
Below is the screenshot
[![error-404][1]][1]
spring:
security:
oauth2:
client:
registration:
okta:
client-id: clientId
client-secret: secret
scope: openid, email
authorization-grant-type: authorization_code
redirect-uri: http://localhost:8082/mms-sso/auth
provider:
okta:
issuer-uri: https://dev-40483106.okta.com/oauth2/default
authorization-uri: https://dev-40483106.okta.com/oauth2/default/v1/authorize
resource:
server: http://localhost:8081
server:
port: 8082
servlet:
context-path: /ui-one
security config
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login**", "/auth/**",
"/auth?**").permitAll().anyRequest().authenticated().and()
.oauth2Login();
Okta config
Sign-in redirect URIs - http://localhost:8082/mms-sso/auth
Sign out redirect URI - http://localhost:8082/mms-sso/, http://localhost:8082/mms-sso/logout
Controller for redirect
#GetMapping("/auth")
String home(#AuthenticationPrincipal OidcUser user) {
return "Welcome to MMS SSO";
}
Your controller mapping is for /auth but in redirect you specify it as /mmo-sso/auth.

Spring cloud with Eureka, Oauth2 and zuul

I am trying to configure the sample https://github.com/dsyer/spring-security-angular/tree/master/oauth2/ui to use eureka for the userAuthorizationUri part but with no luck so far. my oauth2 server is registered via eureka
server:
port: ${PORT:${SERVER_PORT:0}}
debug:
security:
user:
password: none
zuul:
routes:
resource:
path: /resource/**
url: http://localhost:9000/resource
user:
path: /user/**
serviceId: authentication-service/uaa/user
spring:
application:
name: ui-service
oauth2:
sso:
home:
secure: false
path: /,/**/*.html
client:
accessTokenUri: http://authentication-service/uaa/oauth/token
userAuthorizationUri: http://authentication-service/uaa/oauth/authorize
clientId: acme
clientSecret: acmesecret
resource:
serviceId: ${PREFIX:}resource
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
MYKEY
-----END PUBLIC KEY-----
logging:
level:
org.springframework.security: DEBUG
eureka:
instance:
metadataMap:
instanceId: ${spring.application.name}:${spring.application.instance_id:${random.int(10000)}}
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/

How to Secure Spring Cloud Config Server

I understand that a Spring Cloud Config Server can be protected using an user name and password , which has to be provided by the accessing clients.
How can i prevent the clients from storing these user name and
password as clear text in the bootstrap.yml files in the client
application/services ?
The very basic "basic authentication" (from here https://github.com/spring-cloud-samples/configserver)
You can add HTTP Basic authentication by including an extra dependency on Spring Security (e.g. via spring-boot-starter-security). The user name is "user" and the password is printed on the console on startup (standard Spring Boot approach). If using maven (pom.xml):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
If you want custom user/password pairs, you need indicate in server configuration file
security:
basic:
enabled: false
and add this minimal Class in your code (BasicSecurityConfiguration.java):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
//#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class BasicSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Value("#{'${qa.admin.password:admin}'}") //property with default value
String admin_password;
#Value("#{'${qa.user.password:user}'}") //property with default value
String user_password;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password(user_password).roles("USER")
.and()
.withUser("admin").password(admin_password).roles("USER", "ACTUATOR");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/encrypt/**").authenticated()
.antMatchers("/decrypt/**").authenticated()
//.antMatchers("/admin/**").hasAuthority("ROLE_ACTUATOR")
//.antMatchers("/qa/**").permitAll()
;
}
}
#Value("#{'${qa.admin.password:admin}'}") allow passwords to be defined in property configuration file, environment variables or command line.
For example (application.yml):
server:
port: 8888
security:
basic:
enabled: false
qa:
admin:
password: adminadmin
user:
password: useruser
management:
port: 8888
context-path: /admin
logging:
level:
org.springframework.cloud: 'DEBUG'
spring:
cloud:
config:
server:
git:
ignoreLocalSshSettings: true
uri: ssh://git#gitlab.server.corp/repo/configuration.git
This works for me.
Edit: Instead of the Class, you can put basic user configuration directly in application.yaml:
security:
basic:
enabled: true
path: /**
ignored: /health**,/info**,/metrics**,/trace**
user:
name: admin
password: tupassword
For Spring Boot 2 the configuration in application.yml are now under spring.security.* (https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#security-properties)
spring.security:
basic:
enabled: true
path: /**
ignored: /health**,/info**,/metrics**,/trace**
user:
name: admin
password: tupassword
Basic authentication configuration that works for me.
Server-side:
Needed depedency: org.springframework.boot:spring-boot-starter-security
bootstrap.yml
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: git#bitbucket.org:someRepo/repoName.git
hostKeyAlgorithm: ssh-rsa
hostKey: "general hostKey for bitbucket.org"
security:
user:
name: yourUser
password: yourPassword
Client-side:
bootstrap.yml
spring:
application:
name: config
profiles:
active: dev
cloud:
config:
uri: http://localhost:8888
username: yourUser
password: yourPassword
management:
security:
enabled: false
Sources: Spring doc security feautres, Spring cloud config client security
encrypted text can be placed in bootstrap.yml.
Check -> http://projects.spring.io/spring-cloud/spring-cloud.html#_encryption_and_decryption

Resources