0

I have developed a RESTful API in Spring which retrieves user info from a database (MongoDB) and returns that data to a client that consumes this REST API. But before the data is retrieved the REST API checks to see if the user is an admin or not. Only the admin can perform GET operations to retrieve user info

So in my securityconfig.java class I have this:

http.authorizeRequests()
            .antMatchers("/users/get/**", "/users/get/**").hasRole("ADMIN");

http.httpBasic();

Now, the users all have their roles and everything is working as expected in the sense that when I call curl adminusername:adminpassword@localhost:8080/users/get/AllUsers

I am able to retrieve all the users because the user with the username of adminusername is an admin and he has permission. But if I replace adminusername with a non-admin username, I get an access denied error.

My question is, is the adminusername:adminpassword part before the @localhost:8080.... the header of the HTTP request?

The reason I ask is because I need to create a client that is able to log in, have his credentials (username and password) verified, and have the username and password used as the session id, so that any time the client makes HTTP request calls after being logged in, the username and password is appended to the header and is processed by the REST API.

The hasRole() of the

http.authorizeRequests()
                .antMatchers("/users/get/**", "/users/get/**").hasRole("ADMIN");

in the security config is dependent on the username:password before the @localhost:8080.... is this the same thing as @RequestHeader of the spring rest API?

Kingamere
  • 9,496
  • 23
  • 71
  • 110

1 Answers1

0

First of all, Http Basic is a way, to send user credentials through header -

var header = {'Authorization': 'Basic '+btoa(username+':'+password)} //javascript

Second thing are authorities for a user. You in your system have to create user, and add them priviliges, for example:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("mati").password("qwerty").roles("ADMIN", "USER").and()
            .withUser("mati2").password("qwerty").roles("USER");
}

These users became later objects from class Principal which has their granted Authorities (like "ROLE_USER" or "ROLE_ADMIN").

When you are calling for example

curl adminusername:adminpassword@localhost:8080/users/get/AllUsers

Spring Security will check for proper Principal (with given username and will check if password matches), load it to the SecurityContext and will check if Principal has authority "ROLE_ADMIN" (by hasRole("ADMIN")). I must add that this was tricky, and I don't remember exactly, if you it washasRole("ADMIN") or hasRole("ROLE_ADMIN").

I hope this will answer your question(s).

Mati
  • 2,476
  • 2
  • 17
  • 24
  • @Thanks for the answer. I have already set the roles and what not. You are also correct that it has to be hasRole("ADMIN") and not hasRole("ROLE_ADMIN"). I tried that and it gave me an error which says to not add 'ROLE' because it already does that for you. So you say that username and password are appended to the header. So now for my client-side, whenever I send an HTTP request, I need to add the username and password to my request correct? – Kingamere Jul 18 '15 at 14:38
  • Yes, this is the way with HttpBasic. But there is also another (more secure) way. You can use Session Id (after login in) and it will use same principal. With Spring Session you can configure it to behave as Authentication Token. With this approach you send username and password only once, and then you send obtained token with every next request. For more information I would suggest you to read about ```HeaderHttpSessionStrategy```. – Mati Jul 18 '15 at 14:53
  • I see now. Now it makes sense. Thank you. – Kingamere Jul 18 '15 at 16:24