I and my team have developed a small spring project. We have jsp pages in which we have written ajax calls and through these calls data is fetched, as JSON, and displayed through javascript. Now we need to add security to both, the JSP pages and REST services.
Our requirements:
The server should be stateless
Client cannot be expected to store cookies.
Credentials sent to the server should not be plain text
I am new to Spring Security so I would appreciate if I can get any help in implementing it.
1 . The server should be state less.
Starting spring 3.1 it is easy as setting an attribute in your spring security http tag.
<http create-session="stateless"> ..</http>
2 . Client cannot be expected to store cookies.
Then I would opt for basic authentication for the rest api and ajax calls.
The client however has to cache the username and password and send it with each request.
3 . Credentials to the server should not be plaintext.
Use HTTPS with a valid SSL Certificate.
Related
Our stack includes the following services, each service runs in a docker container:
Front-end in React
Backend service based on Spring boot "resource-service"
Keycloak
Other backend service (consumer)
Both the front-end and the consumer services communicate with the backend using REST API.
We use Keycloak as our user management and authentication service.
We would like to integrate our Spring based service "resource-service" with Keycloak by serving both web application and a service flows:
Web application - React based front-send that should get a redirect 302 from the "resource-service" and send the user / browser to login in the Keycloak site and then return to get the requested resource.
Server 2 Server coomunication - A server that need to use the "resource-service" API's should get 401 in case of authentication issues and not a redirection / login page.
There are few options to integrate Spring with Keycloak:
Keycloak Spring Boot Adapter
Keycloak Spring Security Adapter
Spring Security and OAuth2
I noticed that there is a "autodetect-bearer-only" in Keycloak documentation, that seems to support exactly that case. But -
There are a lot of integration options and I'm not sure what is the best way to go, for a new Spring boot service.
In addition, I didn't find where to configure that property.
I've used approaches one and two and in my opinion, if you are using Spring Boot, use the corresponding adapter, use the Spring Security adapter if you're still using plain Spring MVC. I've never seen the necessity for the third approach as you basically have to do everything on your own, why would anyone not use the first two methods?
As for using the Spring Bood adapter, the only configuration necessary is the following:
keycloak:
bearer-only: true
auth-server-url: your-url
realm: your-realm
resource: your-resource
And you're done. The bearer-only is so that you return 401 if a client arrives without a bearer token and isn't redirected to a login page, as you wanted. At least that's what's working for us :-)
After that, you can either use the configuration for securing endpoints but it's a bit more flexible to either use httpSecurity or #EnableGlobalMethodSecurity which we're doing with e. g. #Secured({"ROLE_whatever_role"}).
If you're using the newest Spring Boot version combined with Spring Cloud, you might run into this issue.
I configure my resource-servers to always return 401 when Authorization header is missing or invalid (and never 302), whatever the client.
The client handles authentication when it is required, token refreshing, etc.: Some of certified OpenID client libs even propose features to ensure user has a valid access-token before issuing requests to protected resources. My favorite for Angular is angular-auth-oidc-client, but I don't know which React lib has same features.
Keycloak adapters for Spring are now deprecated. You can refer to this tutorials for various resource-server security configuration options. It covers uses cases from most simple RBAC to building DSL like: #PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
I need to create a SpringBoot RESTful API to be consumed either by a web project or a mobile app.
My question is how to secure it without the typically basic authorization that returns you a "jsessionid" to the web browser and mantains the session with it. It's not a problem for the web project, because it could store that jsessionid. But how about to secure the mobile app request to the API?
Sorry for my english. Thanks.
One of the architectural constraints of REST is that it must be stateless.
Your REST API must not have sessions that authenticate the client. Instead, the client should pass some sort of token, commonly placed in the Authentication HTTP Header.
JWT and OAuth 2.0 are both very popular ways of doing this, and you can absolutely use HTTP Basic Authentication with OAuth 2.0 if you wish.
Here's an article called Stateless Authenticaiton with Spring Security and JWT. Hopefully that will help!
You can use basic authentication. It work sending username and password on each request but don't need save the sessionid in the client.
Here are a sample application with basic authentication:
http://www.baeldung.com/spring-security-basic-authentication
If you don't save anything in the server session you don't need save the jsessionid in the client.
How do i call an api from an app secured by spring security.
I have a api provider completely secured with spring security.
Now i want to allow other clients/service to consume my rest from their apps. eg using jquery, php, etc. But my app is secured.
Your assistance will be highly appreciated.
A REST API is a set of URLs. You access these URLs secured by Spring in the same way you'd access any secured Web app.
That is, use a Web client, establish a session by using the authentication method configured, and send the HTTP method request you want.
I want to integrate spring security in REST web services but when the url is hit default login page displayed by the Spring Security. How I can authenticate REST web service without any displaying any login page or any JSP page.
You can configure Spring security in your application, using preAuthorization in #EnableGlobalSecurityMEthod ~, I think is this annotation. In your restservice, using #PreAuthorization("<role>"), I think is this annotation. This works very good.
If you have basic authentication, then you can simply post username/password encoded in Authorization http header from client.
Or you can have PreAuthenticatedAuthenticationProvider configured with a pre-authentication RequestHeaderAuthenticationFilter
I have a Spring MVC application that uses Spring Security to handle user login authentication, which works fine.
Now I want to add some Ember.js and Angular.js code to the HTML pages that accesses the Spring RESTful web services (which just return JSON data).
How do I bind the user login authentication to the authentication for the RESTful web services? In other words, I want to make it so that the RESTful web services can only be accessed once a user has logged in. That way, the Angular.js and Ember.js libraries can access these RESTful web services securely from my user pages only without anyone else being able to directly call them.
I read on one other post that Spring Security was never meant to be used with a full Ajax framework, is that true? I hope this is not the case. I'd imagine that this type of thing must be pretty common now as there are so many AJAX client side frameworks that work based off accessing a JSON/RESTful API.
It is certainly not true that Spring Security was never meant to be or cannot be used in AJAX applications. I have two applications in production that use Spring Security as well as AJAX and more applications under development with the same mix.
If you are going to use EmberJS or AngularJS in an existing web application with Spring Security working, you should not face too many problems if you simply add the JavaScript library to your project. This is because once your users are authenticated, any normal HTTP requests will be treated as authenticated as well because the browser will ensure that session information is passed back and forth using cookies or URL parameters, as appropriate. You can see one of my working examples on Github for Spring Security and EmberJS integration.
The only thing you may need to worry about is CSRF tokens for form submissions using AJAX. The latest Spring Security documentation has a small section dedicated to this so you should not face too many problems getting that to work either. However, I would like to clarify that this particular issue is not specific to Spring Security. CSRF protection typically involves including a secure, randomly generated token with every HTTP POST request. The challenge arises from making existing JavaScript libraries aware of this token and how it should be included in HTTP POST requests. This would be a challenge in any application, not just those using Spring Security.
If however you will work with stateless clients, such as, mobile devices, you will be unable to rely on the default Spring Security mechanism of storing the user credentials in HTTP Session because HTTP requests will not have information to tie them to a session. This again is not specific to a Spring or Spring Security application because the constraint is imposed by the nature of the client and the client-server communication rather than any server-side technology. In such circumstances you will need to pass some authentication token in the HTTP headers for the application to maintain security state on the server side. I have a working example for this as well. If you need more details, there are articles on the web that explain how to do something like this with Spring Security.