React request to Spring Boot database fails due to Spring Security [duplicate] - java

I have created this Spring Boot backend for a university assignment, which requires authorization/authentication. I have made the api work fine standalone , and the calls go through with correct authorization/authentication through Postman requests. But when i try to call the api from a react app, it always returns unauthanticaded 401.
I removed the security completely from the api, just to see if it would work, it does , the api calls return the results as expected (without Spring Security). But when i re-add Spring security only the Postman requests work.
Javascript Fetch requests don't work (Returning 401)
var myHeaders = new Headers();
myHeaders.append("Authorization", "Basic " + btoa("root:root"));
const res = await fetch("http://localhost:7979/api/users", myHeaders)
console.log(res);
const data = await res.json();
console.log(data);
Console Output:
and wget/curl requests don't work with both outputing Connection Refused
Successful Postman request:
Here is the security config from the spring boot backend:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig
{
#Resource
private DataSource dataSource;
#Autowired
private UserDetailsService userDetailsService;
#Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception
{
http.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.POST , "/api/users").permitAll()
.requestMatchers( "/api/authority").hasAuthority(Constants.ADMIN)
.anyRequest().authenticated()
)
.formLogin().permitAll()
.and().logout().permitAll()
.and().userDetailsService(userDetailsService)
.cors()
.and().csrf().disable()
.httpBasic();
http.headers().frameOptions().sameOrigin();
return http.build();
}
#Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
}
the spring backend is run on localhost:7979
and the react app is run on localhost:3000
also, maybe important, i am on windows and run the React app on Windows Subsystem for Linux but the spring app but the default runner of Intellij.
I'm quite stumped and i can't figure out how to debug Spring Security, everyone just says enable logging which i have done but the Spring Security Logging offers 0 useful info (unless i don't understand what I'm seeing)
Update:
So wsl is a bit of a problem, i have this script on .zshrc on wsl that get the ip of the windows host (i don't know how it works, a person here told me to add it and it worked)
script:
export winhost=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
if [ ! -n "$(grep -P "[[:space:]]winhost" /etc/hosts)" ]; then
printf "%s\t%s\n" "$winhost" "winhost" | sudo tee -a "/etc/hosts"
fi
so now if i use the winhost instead of localhost wget/curl works fine
Successful wget request:
Successful curl request:
I tried doing the same on the React app but it came up with a new error
I also tried running the React app on windows instead of wsl , but i had the same result:
Update Update:
I found a way to activate logging on spring security, here are the log for a successful request:
2023-01-26T02:00:33.435+02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.security.web.FilterChainProxy : Securing GET /api/users
Hibernate:
select
u1_0.`id`,
u1_0.`AFM`,
u1_0.`address`,
u1_0.`email`,
u1_0.`enabled`,
u1_0.`password`,
u1_0.`phone_number`,
u1_0.`username`
from
`users` u1_0
where
u1_0.`username`=?
Hibernate:
select
a1_0.`user_id`,
a1_1.`id`,
a1_1.`authority`
from
`user_authorities` a1_0
join
`authorities` a1_1
on a1_1.`id`=a1_0.`authority_id`
where
a1_0.`user_id`=?
Hibernate:
select
u1_0.`authority_id`,
u1_1.`id`,
u1_1.`AFM`,
u1_1.`address`,
u1_1.`email`,
u1_1.`enabled`,
u1_1.`password`,
u1_1.`phone_number`,
u1_1.`username`
from
`user_authorities` u1_0
join
`users` u1_1
on u1_1.`id`=u1_0.`user_id`
where
u1_0.`authority_id`=?
2023-01-26T02:00:33.508+02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.s.a.dao.DaoAuthenticationProvider : Authenticated user
2023-01-26T02:00:33.508+02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.s.w.a.www.BasicAuthenticationFilter : Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=gr.hua.dit.it22023_it22026.models.SecurityUserDetails#2e536336, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=172.20.196.70, SessionId=null], Granted Authorities=[ADMIN]]
2023-01-26T02:00:33.509+02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.security.web.FilterChainProxy : Secured GET /api/users
Hibernate:
select
u1_0.`id`,
u1_0.`AFM`,
u1_0.`address`,
u1_0.`email`,
u1_0.`enabled`,
u1_0.`password`,
u1_0.`phone_number`,
u1_0.`username`
from
`users` u1_0
Hibernate:
select
a1_0.`user_id`,
a1_1.`id`,
a1_1.`authority`
from
`user_authorities` a1_0
join
`authorities` a1_1
on a1_1.`id`=a1_0.`authority_id`
where
a1_0.`user_id`=?
Hibernate:
select
u1_0.`authority_id`,
u1_1.`id`,
u1_1.`AFM`,
u1_1.`address`,
u1_1.`email`,
u1_1.`enabled`,
u1_1.`password`,
u1_1.`phone_number`,
u1_1.`username`
from
`user_authorities` u1_0
join
`users` u1_1
on u1_1.`id`=u1_0.`user_id`
where
u1_0.`authority_id`=?
Hibernate:
select
a1_0.`user_id`,
a1_1.`id`,
a1_1.`authority`
from
`user_authorities` a1_0
join
`authorities` a1_1
on a1_1.`id`=a1_0.`authority_id`
where
a1_0.`user_id`=?
Hibernate:
select
a1_0.`user_id`,
a1_1.`id`,
a1_1.`authority`
from
`user_authorities` a1_0
join
`authorities` a1_1
on a1_1.`id`=a1_0.`authority_id`
where
a1_0.`user_id`=?
Hibernate:
select
u1_0.`authority_id`,
u1_1.`id`,
u1_1.`AFM`,
u1_1.`address`,
u1_1.`email`,
u1_1.`enabled`,
u1_1.`password`,
u1_1.`phone_number`,
u1_1.`username`
from
`user_authorities` u1_0
join
`users` u1_1
on u1_1.`id`=u1_0.`user_id`
where
u1_0.`authority_id`=?
And here are the logs for a failed request:
2023-01-26T02:02:23.041+02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.security.web.FilterChainProxy : Securing GET /api/users
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#456e1a23
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.security.web.FilterChainProxy : Securing GET /error
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-01-26T02:02:23.042+02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#456e1a23
I don't understand the fail request logs at all, can any spring boot security expert help?

issue was in javascript
const res = await fetch("http://localhost:7979/api/users", headers);
should have been
const res = await fetch("http://localhost:7979/api/users", {headers:headers})

Related

Why does Spring Security 6 not create sessions when authenticating with curl and basic auth?

I recently upgraded to Spring Security 6, and have found that authenticating using basic auth from JS or from curl no longer works but authenticating with basic auth using Java's HttpClient does work. My goal is to be able to authenticate with all approaches.
The app uses Java 17, Spring Security 6, and Spring Session 3. It has a "login" endpoint which is just a convenience endpoint that is expected to be hit with basic auth and create a session, and it returns a User object. The session id should be used for subsequent requests to other endpoints.
The curl command is like so:
curl -kv --user admin:admin "https://localhost:9000/login"
VS the HttpClient is configured like so and calling HttpClient.get(loginUrl)
HttpClient.newBuilder()
       .connectTimeout(Duration.ofSeconds(300))
       .cookieHandler(new CookieManager())
       .authenticator(new BasicAuthenticator(username, password))
       .sslContext(createSsl())
       .build();
public class BasicAuthenticator extends Authenticator {
   private PasswordAuthentication authentication;
   public BasicAuthenticator(String username, String password) {
       authentication = new PasswordAuthentication(username, password.toCharArray());
   }
   #Override
   public PasswordAuthentication getPasswordAuthentication() {
       return authentication;
   }
}
The security configuration is the block below... In upgrading to SpringSecurity 6 I added the requireExplicitSave() method, I have suspicions around this because my trouble is around saving sessions, but the added code is supposed to have spring security using the old functionality.
http
   .securityContext( securityContext -> securityContext.requireExplicitSave(false))
   .authorizeHttpRequests((authz) -> authz
           .requestMatchers(openEndpoints).permitAll()
           .anyRequest().authenticated()
   )
   .httpBasic()
       .and()
   .csrf()
       .disable()
   .exceptionHandling()
       .accessDeniedHandler((req, resp, e) -> e.printStackTrace() )
       .and()
   .logout()
       .invalidateHttpSession(true)
       .clearAuthentication(true);
I turned on request logging, security logging, and SQL logging. The SQL is all the same, and the basic auth request is always authenticated for all scenarios. The headers are different, but I can't see the headers for the HttpClient preflight call, and of the headers I do see, I don't know why authentication or session creation would work for one set of headers but not the other.
The core of the problem seems to be that the login request from the HttpClient ends with a session being created and the request from curl does not. Note that the big difference in the server logs when using curl is "Failed to create a session, as response has been committed. Unable to store SecurityContext." However even stepping through the spring security code I can't tell what is causing the difference. 
See logs here:
CURL
2022-12-14T16:38:07.594-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.security.web.FilterChainProxy : Securing GET /login
2022-12-14T16:38:07.597-05:00 DEBUG 92726 --- [nio-9000-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-12-14T16:38:07.704-05:00 DEBUG 92726 --- [nio-9000-exec-1] org.hibernate.SQL : select u1_0.id,u1_0.display_name,u1_0.email,u1_0.enabled,u1_0.password,u1_0.registration_time,r1_0.user_id,r1_0.role_id,u1_0.username from app_user u1_0 join user_role r1_0 on u1_0.id=r1_0.user_id where u1_0.username=?
2022-12-14T16:38:07.797-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.s.a.dao.DaoAuthenticationProvider : Authenticated user
2022-12-14T16:38:07.799-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.s.w.a.www.BasicAuthenticationFilter : Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=admin, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_ADMIN, ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=null], Granted Authorities=[ROLE_ADMIN, ROLE_USER]]
2022-12-14T16:38:07.801-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.security.web.FilterChainProxy : Secured GET /login
2022-12-14T16:38:07.805-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.w.f.CommonsRequestLoggingFilter : Before request [GET /login, headers=[host:"localhost:9000", authorization:"Basic YWRtaW46YWRtaW4=", user-agent:"curl/7.84.0", accept:"*/*"]]
2022-12-14T16:38:07.816-05:00 DEBUG 92726 --- [nio-9000-exec-1] horizationManagerBeforeMethodInterceptor : Authorizing method invocation ReflectiveMethodInvocation: public com.seebie.dto.User com.seebie.server.controller.UserController.login(java.security.Principal); target is of class [com.seebie.server.controller.UserController]
2022-12-14T16:38:07.822-05:00 DEBUG 92726 --- [nio-9000-exec-1] horizationManagerBeforeMethodInterceptor : Authorized method invocation ReflectiveMethodInvocation: public com.seebie.dto.User com.seebie.server.controller.UserController.login(java.security.Principal); target is of class [com.seebie.server.controller.UserController]
2022-12-14T16:38:07.826-05:00 DEBUG 92726 --- [nio-9000-exec-1] org.hibernate.SQL : select u1_0.id,u1_0.display_name,u1_0.email,u1_0.enabled,u1_0.password,u1_0.registration_time,u1_0.username from app_user u1_0 where u1_0.username=?
2022-12-14T16:38:07.832-05:00 DEBUG 92726 --- [nio-9000-exec-1] org.hibernate.SQL : select r1_0.user_id,r1_0.role_id from user_role r1_0 where r1_0.user_id=?
2022-12-14T16:38:07.836-05:00 DEBUG 92726 --- [nio-9000-exec-1] org.hibernate.SQL : select a1_0.user_id,a1_0.id,a1_0.city,a1_0.line1,a1_0.state,a1_0.zip from address a1_0 where a1_0.user_id=?
2022-12-14T16:38:07.840-05:00 DEBUG 92726 --- [nio-9000-exec-1] org.hibernate.SQL : select s1_0.principal_name,s1_0.primary_id,s1_0.session_id from spring_session s1_0 where s1_0.principal_name=?
2022-12-14T16:38:07.871-05:00 DEBUG 92726 --- [nio-9000-exec-1] o.s.w.f.CommonsRequestLoggingFilter : REQUEST DATA : GET /login, headers=[host:"localhost:9000", authorization:"Basic YWRtaW46YWRtaW4=", user-agent:"curl/7.84.0", accept:"*/*"]]
2022-12-14T16:38:07.873-05:00 WARN 92726 --- [nio-9000-exec-1] w.c.HttpSessionSecurityContextRepository : Failed to create a session, as response has been committed. Unable to store SecurityContext.
2022-12-14T16:38:07.873-05:00 DEBUG 92726 --- [nio-9000-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
HttpClient
2022-12-14T06:31:28.390-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.security.web.FilterChainProxy : Securing GET /login
2022-12-14T06:31:28.420-05:00 DEBUG 85610 --- [o-auto-1-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-12-14T06:31:28.913-05:00 DEBUG 85610 --- [o-auto-1-exec-1] org.hibernate.SQL : select u1_0.id,u1_0.display_name,u1_0.email,u1_0.enabled,u1_0.password,u1_0.registration_time,r1_0.user_id,r1_0.role_id,u1_0.username from app_user u1_0 join user_role r1_0 on u1_0.id=r1_0.user_id where u1_0.username=?
2022-12-14T06:31:29.102-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.s.a.dao.DaoAuthenticationProvider : Authenticated user
2022-12-14T06:31:29.103-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.s.w.a.www.BasicAuthenticationFilter : Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=admin, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_ADMIN, ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=19ab0971-5fb3-47fd-a4f9-cdde1ad24883], Granted Authorities=[ROLE_ADMIN, ROLE_USER]]
2022-12-14T06:31:29.108-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.security.web.FilterChainProxy : Secured GET /login
2022-12-14T06:31:29.136-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.w.f.CommonsRequestLoggingFilter : Before request [GET /login, headers=[authorization:"Basic YWRtaW46YWRtaW4=", content-length:"0", host:"localhost:64723", user-agent:"Java-http-client/17.0.2", cookie:"SESSION=MTlhYjA5NzEtNWZiMy00N2ZkLWE0ZjktY2RkZTFhZDI0ODgz", Content-Type:"application/json;charset=UTF-8"]]
2022-12-14T06:31:29.274-05:00 DEBUG 85610 --- [o-auto-1-exec-1] horizationManagerBeforeMethodInterceptor : Authorizing method invocation ReflectiveMethodInvocation: public com.seebie.dto.User com.seebie.server.controller.UserController.login(java.security.Principal); target is of class [com.seebie.server.controller.UserController]
2022-12-14T06:31:29.332-05:00 DEBUG 85610 --- [o-auto-1-exec-1] horizationManagerBeforeMethodInterceptor : Authorized method invocation ReflectiveMethodInvocation: public com.seebie.dto.User com.seebie.server.controller.UserController.login(java.security.Principal); target is of class [com.seebie.server.controller.UserController]
2022-12-14T06:31:29.373-05:00 DEBUG 85610 --- [o-auto-1-exec-1] org.hibernate.SQL : select u1_0.id,u1_0.display_name,u1_0.email,u1_0.enabled,u1_0.password,u1_0.registration_time,u1_0.username from app_user u1_0 where u1_0.username=?
2022-12-14T06:31:29.392-05:00 DEBUG 85610 --- [o-auto-1-exec-1] org.hibernate.SQL : select r1_0.user_id,r1_0.role_id from user_role r1_0 where r1_0.user_id=?
2022-12-14T06:31:29.409-05:00 DEBUG 85610 --- [o-auto-1-exec-1] org.hibernate.SQL : select a1_0.user_id,a1_0.id,a1_0.city,a1_0.line1,a1_0.state,a1_0.zip from address a1_0 where a1_0.user_id=?
2022-12-14T06:31:29.413-05:00 DEBUG 85610 --- [o-auto-1-exec-1] org.hibernate.SQL : select s1_0.principal_name,s1_0.primary_id,s1_0.session_id from spring_session s1_0 where s1_0.principal_name=?
2022-12-14T06:31:29.678-05:00 DEBUG 85610 --- [o-auto-1-exec-1] o.s.w.f.CommonsRequestLoggingFilter : REQUEST DATA : GET /login, headers=[authorization:"Basic YWRtaW46YWRtaW4=", content-length:"0", host:"localhost:64723", user-agent:"Java-http-client/17.0.2", cookie:"SESSION=MTlhYjA5NzEtNWZiMy00N2ZkLWE0ZjktY2RkZTFhZDI0ODgz", Content-Type:"application/json;charset=UTF-8"]]
2022-12-14T06:31:29.680-05:00 DEBUG 85610 --- [o-auto-1-exec-1] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=admin, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_ADMIN, ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=19ab0971-5fb3-47fd-a4f9-cdde1ad24883], Granted Authorities=[ROLE_ADMIN, ROLE_USER]]] to HttpSession [org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper#7ba784f2]
2022-12-14T06:31:29.680-05:00 DEBUG 85610 --- [o-auto-1-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
Note the session in headers for the HttpClient call... I think HttpClient makes a preflight auth call that gets a 401 and then makes the "real" call with the credentials, at least that's how it was in Java 11.
I think if I understood the difference in how these calls are being made/handled that causes one technique to work but not the other, I would be able to solve the problem. So that really is the question: What is the difference in spring security 6 (along with spring session) handling session creation when using Java 17's HttpClient vs curl?
[UPDATE] to anyone who read this far: the behavior is actually expected behavior for Spring Security. A full discussion and explanation are in the spring security issue that I had opened here
Well, if we are not going to investigate why preflight requests make sense (IMO, that seems to be a bug), the explanation of what has been changed in spring 6 is following:
as was mentioned in Session Management Migrations now Spring does not enable SecurityContextPersistenceFilter by default, however in Spring 5 SecurityContextPersistenceFilter was responsible for saving SecurityContext in http session (and hence creating it) unless that was explicitly disabled. Now in order to return previous behaviour you desire you need to setup SecurityContextRepository via:
http.securityContext(securityContext -> securityContext.
securityContextRepository(new HttpSessionSecurityContextRepository())
)

Java Spring Security Authentication Server does not display error description

My Java Spring Authentication and Authorization Server is working.
I want to solve the errors in the requests I send from a client according to the OAuth2 flow. But none of the errors I get are detailed. For example, this request sent to /oauth2/authorize:
https://MY_DOMAIN/authorize?
response_type=code&
client_id=MY_CLIENT_ID&
redirect_uri=MY_CALLBACK_URL&
scope=SCOPE&
state=STATE
Gives the following error after I enter credentials:
My goal is not to resolve the error here, but there are different errors I get like this and I need to see a more informative error message so I can debug them all.
The console also has a non-informative output that goes like this:
...
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] o.a.c.c.C.[Tomcat].[localhost] : Processing ErrorPage[errorCode=0, location=/error]
2022-08-15 15:52:33.739 DEBUG 50827 --- [nio-9000-exec-4] o.s.security.web.FilterChainProxy : Securing GET /error?protocol=oauth2&response_type=code&access_type&client_id=articles-client&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Flms%2Flogin&scope=openid%20articles.read&state=XqqDv6wx6O&code_challenge_method=plain&code_challenge=e964fe0c4b609ef3cf29658efc6077e7feb591f78c458c2092aa56c9
...

Jhipster new Roles - Full authentication is required

I have a problem where I cannot acces any url while logged in on an accont with a custom defined ROLE.
To create the new roles for my app, I added my new roles in the AuthoritiesConstants class and in authorities.csv.
Then I manually inserted my new desired roles : ROLE_STUDENT and ROLE_PROFESOR in my h2-database.
Then I logged in on the admin account and tried and succeeded to create a new user with the ROLE_STUDENT.
Then I logged on to this new account and tried to access http://localhost:9000/api/users to get the full list of users.
I got the following error :
2020-03-19 10:59:05.687 DEBUG 13892 --- [ XNIO-1 task-15] base.aop.logging.LoggingAspect : Enter: base.repository.CustomAuditEventRepository.add() with argument[s] = [AuditEvent [timestamp=2020-03-19T08:59:05.686Z, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null, type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]]
2020-03-19 10:59:05.691 DEBUG 13892 --- [ XNIO-1 task-15] base.aop.logging.LoggingAspect : Exit: base.repository.CustomAuditEventRepository.add() with result = null
2020-03-19 10:59:05.693 WARN 13892 --- [ XNIO-1 task-15] o.z.problem.spring.common.AdviceTraits : Unauthorized: Full authentication is required to access this resource
2020-03-19 10:59:05.695 WARN 13892 --- [ XNIO-1 task-15] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource]
In my SecurityConfiguration class, this url falls under .antMatchers("/api/**").authenticated(). So I was supposed to be able to access it from any account, as long as I am logged in.
To my dismay, it seems I cannot access any URL, apart from the home page, from this account. I manually checked my database to see if the user has been created and has the correct role. All is well there.
Can someone help me solve this ?
You have to open the routes to the new roles too, this is done on the client side. This is more or less how it looks if you use angular.
The home component is open to anyone as you can see in the file home.route.ts.
export const HOME_ROUTE: Route = {
path: '',
component: HomeComponent,
data: {
authorities: [], // <- Empty, so anyone can access the home
pageTitle: 'home.title'
}
};
On the other hand, if you want to grant access to a new role in a regular component, you'll have to add it to the valid authorities array in your [entity-name].route.ts.
export const fooRoute: Routes = [
{
...
data: {
authorities: ['ROLE_STUDENT', 'ROLE_PROFESOR'],
...
},
...
That gives access to any user who has either ROLE_STUDENT or ROLE_PROFESOR, but not regular users (who only have ROLE_USER). This was just an example.
In any case, if I understood your question correctly, you were trying to access an api/... mapping directly in your browser. That's not a good idea and it's good that it fails since the client usually adds stuff to most requests so that they are properly handled and validated by the server (XSRF, auth token, ...).

Authentication issue with spring security, JWT on resource API

I am having a issue related to authentication where I am getting logged out of my app when trying to GET from an endpoint that was created from a POST (HTTTP STATUS 201) I see the following errors. The backend is seeing the user as anonymousUser while I am logged in but works fine for another endpoint in the same file :
2018-10-22 11:33:35.251 DEBUG 2124 --- [ XNIO-8 task-23]
c.c.link.aop.logging.LoggingAspect : Enter:
org.springframework.boot.actuate.audit.AuditEventRepository.add() with
argument[s] = [AuditEvent [timestamp=Mon Oct 22 11:33:35 PDT 2018,
principal=anonymousUser, type=AUTHORIZATION_FAILURE,
data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#fffed504:
RemoteIpAddress: 127.0.0.1; SessionId:
_5aP-S8x27gGSIjtbkR6EwrWOD9Yybnd-4M3z0ol, type=org.springframework.security.access.AccessDeniedException,
message=Access is denied}]] 2018-10-22 11:33:35.258 DEBUG 2124 --- [
XNIO-8 task-23] c.c.link.aop.logging.LoggingAspect : Exit:
org.springframework.boot.actuate.audit.AuditEventRepository.add() with
result = null 2018-10-22 11:33:35.343 WARN 2124 --- [ XNIO-8 task-23]
o.z.p.spring.web.advice.AdviceTrait : Unauthorized: Full
authentication is required to access this resource
The same resource (DeliveryResource.java) has an endpoint that works fine
the only difference between both end points is one is /getList (this one is working fine) VS. /getPackingListReport/{number} (this one fails authentication).
The API definitions are shown below:
#GetMapping("/getPackingListReport/{number}")
#Secured(AuthoritiesConstants.USER)
#Timed
public ArrayList<WebOrder> getPackingListReportFromDB(#PathVariable("number") long packingListNbr)
vs.
#GetMapping("/getList")
#Secured(AuthoritiesConstants.USER)
#Timed
public WebOrder getList(#RequestParam(value = "custid") long custid,#RequestParam(value = "pId") long pId) {
I found the problem.
I was using the following for the "/getList" mapping:
// call dao to insert to DB the list and then call the stored proc
URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/rest/getPackingListReport/{packingListNumber}").buildAndExpand(packingListNumber).toUri();
return ResponseEntity.created(location).build();
to return a created resource URI (HTTP STATUS 201) after a POST. That path contained the incorrect URI starting with , "http://localhost" when jHipster is currently default set to only handle and look for "/api" or in my case i added "/rest/api/*" on the Angular5 side.
I fixed the issue by filtering out any characters before "/api/" after receiving the URL.

spring oauth obtain user details from token

i want to use spring and oauth and so far it seemed to work.
now i added a zuul proxy that is configured like that:
spring:
oauth2:
sso:
home:
secure: false
path: /,/**/*.html
client:
accessTokenUri: http://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/token
userAuthorizationUri: http://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/authorize
clientId: webapp
clientSecret: secret
resource:
id: apis
userInfoUri: http://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/rest/me
preferTokenInfo: false
whenever i try to access an resource server it tries to verify my authentication but my authserver endpoint seems to return text/html instead of json.
Created GET request for "http://localhost:8091/userauth/rest/me"
2015-11-24 14:07:12.275 DEBUG 3601 --- [nio-8080-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : Setting request Accept header to [application/json, application/*+json]
2015-11-24 14:07:12.287 DEBUG 3601 --- [nio-8080-exec-3] o.s.s.oauth2.client.OAuth2RestTemplate : GET request for "http://localhost:8091/userauth/rest/me" resulted in 200 (OK)
2015-11-24 14:07:12.288 INFO 3601 --- [nio-8080-exec-3] o.s.c.s.o.r.UserInfoTokenServices : Could not fetch user details: class org.springframework.web.client.RestClientException, Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map] and content type [text/html;charset=UTF-8]
i already forced json and when accessing auth server directly via curl i get json formatted principal.
#RequestMapping(value="/me", produces = "application/json")
public Principal getCurrentLoggedinUser(Principal user){
return user;
}
any ideas how to send json to my zuul proxy so it can verify my authentication?

Categories