I am trying to retrieve logged in user in my Java Application. I tried to call it from angular application authentication module but it did not worked well. So finally setup username and password in Insomnia as basic authentication and then called. Still at API side unable to retrieve user. I have tried various ways. But all are returning null. Not sure what is going wrong.
Secondly in response it is giving CORS issue. I implemented WebSecurityConfig for same but no luck.
API
package com.controller;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
@CrossOrigin
@RestController()
public class AbcController {
@GetMapping("/getUserName")
public String getUserName(HttpServletRequest request){
System.out.println(request);
System.out.println(request.getRemoteUser()); //prints null
System.out.println(request.getUserPrincipal()); //prints null
//prints anonymousUser
System.out.println(SecurityContextHolder.getContext().getAuthentication().getName());
return request.getRemoteUser();
}
@GetMapping("/getUserNamePrincipal")
//principal is null
public String getUserNamePrincipal (Principal principal ){
System.out.println("principal.getName() : "+principal.getName());
return principal.getName();
}
@GetMapping("/getUserNameAuthentication")
//authentication is null
public String getUserNameAuthentication(Authentication authentication){
System.out.println("authentication.getName() : "+authentication.getName());
return authentication.getName();
}
@GetMapping("/getUserNameAuthenticationPrincipal")
//userDetails is null
public String getUserNameAuthenticationPrincipal(@AuthenticationPrincipal UserDetails userDetails){
System.out.println("userDetails.getUsername() : "+userDetails.getUsername());
return userDetails.getUsername();
}
}
Config
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import javax.servlet.http.HttpServletRequest;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
return new CorsConfiguration().applyPermitDefaultValues();
}
});
}
}
POM
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.3.0.RELEASE</version>
<classifier>sources</classifier>
</dependency>
5
It looks like your endpoints are not protected by Spring Security.
If you apply the following configuration for your security context it should solve the issue:
@Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors().disable()
.authorizeRequests().anyRequest().authenticated()
.and().httpBasic();
}
Basically it tells Spring Security to allow CORS (for convenience of quickly testing with Angular), then that all requests should be authenticated, and finally to allow basic authentication (username + password).
You can then perform a request on one of your endpoint configuring your HTTP client to use basic auth then you should get your current user name in the response.
ex: curl -v -u user:07db6b99-a70f-4d26-9c35-64275be8fb5e --basic localhost:8080/getUserNameAuthenticationPrincipal
where 07db6b99-a70f-4d26-9c35-64275be8fb5e is the generated password by Spring Security at the begining of your logs:
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _
( ( )___ | '_ | '_| | '_ / _` |
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.0.RELEASE)
2024-09-04 15:24:28.897 INFO 51553 --- [ main] com.example.demoso.DemoSoApplication : Starting DemoSoApplication on APLAFAT351406.local with PID 51553 (/Users/gillesgardet/repositories/demo-so/target/classes started by gillesgardet in /Users/gillesgardet/repositories/demo-so)
2024-09-04 15:24:28.898 INFO 51553 --- [ main] com.example.demoso.DemoSoApplication : No active profile set, falling back to default profiles: default
2024-09-04 15:24:29.226 INFO 51553 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2024-09-04 15:24:29.228 INFO 51553 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-09-04 15:24:29.228 INFO 51553 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.35]
2024-09-04 15:24:29.248 INFO 51553 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-09-04 15:24:29.248 INFO 51553 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 335 ms
2024-09-04 15:24:29.293 INFO 51553 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 07db6b99-a70f-4d26-9c35-64275be8fb5e
I hope it helped.
BTW you should upgrade your spring-boot dependencies because 2.3 is deprecated since a long time.
edit: here I’ve disabled CORS for convenience, you should of course never do this and instead handle this appropriately on Angular to send back the token
2