Spring boot app with OAuth 2.0 Azure AD Authentication throws invalid credentials in Azure App Services - spring

I have deployed on Azure App Service. This web app is required authentication. I have config all Authencation base on Azure Document. All most are finished . When I tried Login into App Services I've gotten invalid Credential.
So What I need to do ?
[enter image description here][1]
Java.file
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
#Autowired
ClientRegistrationRepository clientRegistrationRepository;
private OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler() {
OidcClientInitiatedLogoutSuccessHandler successHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
successHandler.setPostLogoutRedirectUri("http://XXXXXX:4200/");
return successHandler;
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**",
"/");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http
.authorizeRequests()
.antMatchers("/organisation/**").permitAll()
.anyRequest().authenticated().and()
.logout()
.logoutSuccessHandler(oidcLogoutSuccessHandler())
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
}
application.properties
azure.activedirectory.tenant-id=0ae51e19-07c8-4e4b-bb6d-648ee58410f4
azure.activedirectory.client-id=232c2998-f0d1-4062-b4fa-33abd0d6af87
azure.activedirectory.client-secret=###
spring.main.allow-bean-definition-overriding=true
pom.file
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.azure.spring/spring-cloud-azure-starter-active-directory -->
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
<version>4.3.0</version>
</dependency>

Related

Open Api Swagger Getting 404

I am trying to access swagger ui via http://localhost:8080/swagger-ui/index.html to reach endpoint templates but getting 404.
I have just added latest version of open api.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.9</version>
</dependency>
I gave permission to swagger endpoints like below.
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(handler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/auth/**", "/swagger-ui.html", "/swagger-ui/index.html", "/swagger-ui/**", "/v3/api-docs/**")
.permitAll()
.anyRequest().authenticated();
httpSecurity.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
and I added Annotation to my main class;
#SpringBootApplication
#OpenAPIDefinition
public class DmsApplication {
public static void main(String[] args) {
SpringApplication.run(DmsApplication.class, args);
}
}

Swagger-ui + Spring Security => localhost:8080/swagger-ui.html <= Not Found 404

I've been doing some investment over this but i couldn't get anywhere, here is my current situation:
1. I'm using Spring Boot + Spring Security and here are my configurations:
.
.
.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
#Autowired
private UserRepository userRepository;
#Autowired
public WebSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
};
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests(authorize -> {
authorize
.antMatchers("/h2-console/**").permitAll() //do not use in production!
.antMatchers("/", "/webjars/**", "/login/**", "/resources/**", "/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**").permitAll();
} )
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and().csrf().ignoringAntMatchers("/h2-console/**", "/api/**");
http.headers().frameOptions().sameOrigin();
};
application.properties:
server.ssl.key-store: classpath:springboot.p12
server.ssl.key-store-password:password
server.ssl.key-store-type: pkcs12
server.ssl.key-alias: springboot
server.ssl.key-password: password
Swagger configuration:
#Configuration
#EnableSwagger2
public class SwaggerConfig { //} extends WebMvcConfigurationSupport {
#Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("enide.logicon.backend.controllers"))
.paths(PathSelectors.any())
.build()
.apiInfo(metaData());
}
.
.
.
Own-generated SSL Certificate up&running, generated to fill the
"editor.swagger.io" https requests needs & to make Basic Auth more secure.
.
.
.
WHY DOES NOT FOUND THE SWAGGER-UI.HTML PAGE? here you have my dependencies:
.
.
.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
.
.
.
**
Also Allowed all paths without need to log in with
antMatchers("/**").permitAll() This allows "editor.swagger.io" to
retrieve data from the API but not /swagger-ui.html, any ideas?
**
Well don't know why that -1 on my question, the answer was there.
What worked for me was changing the dependencies for this one:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>

Spring Boot 2.5.3 OAuth2 - Auth-Server and Webservice separate, Login error

Following the example on https://developer.okta.com/blog/2019/03/12/oauth2-spring-security-guide using the projects Create an OAuth 2.0 Server and Build Your Client App I cannot get it running without error.
I don't use Thymeleaf, as my Webservice returns data, not a page.
OAuth 2.0 Server project
#SpringBootApplication
#EnableResourceServer
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
}
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
public AuthorizationServerConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("abcd")
.secret(passwordEncoder.encode("fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9"))
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true)
.redirectUris("http://localhost:8082/login/oauth2/code/");
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");;
}
}
#Configuration
#Order(1)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("john")
.password(passwordEncoder().encode("doe"))
.roles("USER");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
#RestController
public class UserController {
#GetMapping("/user/me")
public Principal user(Principal principal) {
return principal;
}
}
application.properties
server.port=8090
pom.xml
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
I omit the context path, which the project originally uses.
Webservice project
#RestController
public class MyRESTController {
#GetMapping("/securedPage")
public String securedPage(Principal principal) {
return "securedPage";
}
#GetMapping("/")
public String index(Principal principal) {
return "index";
}
}
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers("/", "/login**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
application.properties
server.port=8082
server.servlet.session.cookie.name=UISESSION
spring.security.oauth2.client.registration.custom-client.client-id=abcd
spring.security.oauth2.client.registration.custom-client.client-secret=fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9
spring.security.oauth2.client.registration.custom-client.client-name=Auth Server
spring.security.oauth2.client.registration.custom-client.provider=custom-provider
spring.security.oauth2.client.registration.custom-client.scope=user_info
spring.security.oauth2.client.registration.custom-client.redirect-uri=http://localhost:8082/login/oauth2/code/
spring.security.oauth2.client.registration.custom-client.client-authentication-method=basic
spring.security.oauth2.client.registration.custom-client.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.custom-provider.authorization-uri=http://localhost:8090/oauth/authorize
spring.security.oauth2.client.provider.custom-provider.token-uri=http://localhost:8090/oauth/token
spring.security.oauth2.client.provider.custom-provider.user-info-uri=http://localhost:8090/user/me
spring.security.oauth2.client.provider.custom-provider.user-name-attribute=name
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
When running both porojects, with localhost:8082 in the web browser I get index as response.
With localhost:8082/securedPage I get redirected to the login page, entering username john and password doe I get the following error page:
Login with OAuth 2.0
[invalid_user_info_response] An error occurred while attempting to retrieve the UserInfo Resource: 404 : [{"timestamp":"2021-07-30T07:58:54.529+00:00","status":404,"error":"Not Found","path":"/user/me"}]
Auth Server
Don't know what the error is causing. Looks like it is related to the Webservice application property and the URL to the UserController in the OAuth 2.0 Server project
spring.security.oauth2.client.provider.custom-provider.user-info-uri=http://localhost:8090/user/me
One additional question is:
Can the login form be avoided? The credentials passed somehow.
If the client is not the web browser but some other application which has no UI. Or perhaps curl. I also have MockMvc tests, so far it was Basic Auth, now OAuth2, how will be those affected?

HttpSecurity Spring Boot configuration

I need to configure 3 endpoints, 2 with authentication and 1 without. The problem is I'm getting all the endpoints with 401 Unauthorized error.
/users no authentication need
/users/1 needs authentication
/details/1 needs authentication
I'm using the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
And I implemented the class:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin")
.password("pwd")
.roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/users").hasAnyRole("ADMIN", "USER")
.anyRequest().permitAll()
.and()
.authorizeRequests()
.anyRequest().hasAnyRole("ADMIN", "USER");
}
}
As per your requirement you just need simple http configuration where GET users can be accessed by all as public url and other need basic auth..below will work for you.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/users").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}

Spring oauth2 and digest authentication will work together

I have added spring oauth2 into my restful service. Most of the services are consumed by my own portal so getting the token then calling the api is fine. However i have exposed some more web services which has to be called without this token concept. Those consumers have username and password.
The best example is Swagger implementation. Where opening the swagger page should be authenticated via digest instead of oauth token.
The below code changes i made but it is not working.
I believe, i no need to call oauth server from the resource server in this case. So just made the below code within the resource server. But seen the problem like after authentication page accepted my credentials it is again rerouting/redirecting to the same authentication page.
Please help.
#Configuration
#EnableResourceServer
public class ResourceServerImpl extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().requestMatchers().antMatchers("/**").and().authorizeRequests()
.antMatchers(HttpMethod.POST, "/url1/path1/path2").hasAnyAuthority( "FUNCTION_FN1")
.antMatchers(HttpMethod.GET, "/url2/path1/path2").hasAnyAuthority( "FUNCTION_FN2")
.antMatchers("/swagger-ui.html").hasRole("USER")
.anyRequest().authenticated()
.and().formLogin().and().httpBasic()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
#Configuration
#EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}
UPDATE
I dont think this is possible to make some request to be authenticated with DIGEST and some are with OAUTH. So currently i made swagger url also to be authenticated with oauth token, instead of digest support.
Yes, it's definitely possible to configure multiple authorization mechanisms in the same application. Distinct instance of WebSecurityConfigurerAdapter should be provided for each mechanism.
#EnableResourceServer and #EnableAuthorizationServer provide corresponding oauth adapters. ApiSecurityConfiguration provides adapter for basic auth.
Here is minimal working sample for basic and oauth2:
#SpringBootApplication
public class TestApp {
#RestController
public static class Endpoints {
// doesn't require any authentication
#RequestMapping("/test")
public String test() {
return "no auth";
}
// requires basic authentication
#RequestMapping("/api/test")
public String apiTest() {
return "basic auth";
}
// requires oauth authentication
#RequestMapping("/oauth/test")
public String oauthTest() {
return "oauth";
}
}
#Configuration
#EnableWebSecurity
public static class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/api/**")
.and()
.authorizeRequests().antMatchers("/api/**").hasRole("USER")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
}
#Configuration
#EnableAuthorizationServer
public static class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("test")
.secret("test")
.authorizedGrantTypes("client_credentials")
.authorities("USER")
.scopes("read", "write", "test")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(120);
}
}
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/oauth/**")
.and()
.authorizeRequests().antMatchers("/oauth/**").authenticated();
}
}
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
}
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>

Resources