- In this lesson we implemented basic project with authentication that comes out of the box Spring Security
We have controller GET http://localhost:8080/hello
and default configuration of Spring Security
And now if we make simple curl http://localhost:8080/hello
then will get
{ "status":401, "error":"Unauthorized", "message":"Unauthorized", "path":"/hello" }
Therefore, we need to define basic auth credentials automatically generated by Spring curl -u user:93a01cf0-794b-4b98-86ef-54860f36f7f3 http://localhost:8080/hello
The response to the call is
Hello!
Also we can use more low level approach
echo -n user:93a01cf0-794b-4b98-86ef-54860f36f7f3 | base64
Get dXNlcjo5M2EwMWNmMC03OTRiLTRiOTgtODZlZi01NDg2MGYzNmY3ZjM=
curl -H "Authorization: Basic dXNlcjo5M2EwMWNmMC03OTRiLTRiOTgtODZlZi01NDg2MGYzNmY3ZjM=" localhost:8080/hello
- In this lesson we will slightly override
out of box logic
added custom UserDetailService implementation (InMemoryUserDetailsManager) and added custom PasswordEncoder implementation
We created user who has a set of credentials (username and password)
Added the user to be managed by our implementation of UserDetailsService
Define a bean of the type PasswordEncoder that our application can use to verify a given password with the one stored and managed by UserDetailsService
curl -iu leo:pass http://localhost:8080/hello
200 OK
- In this part we will customize the handling of authentication and authorization, by defining a bean of type SecurityFilterChain
It makes sense, I can do it this way, but for some reason it doesn't work.
- In this topic, Let's try to create custom AuthProvider (consist and manage user-details and pass-encoder)
- Today, we impl relly custom user-details-service (not just modified InMemoryUserDetailsService, but implemented own class ... impl UDS).
Also let's highlight a few best practice:
- Create UserDetailsServiceImpl and PasswordEncoder in one class, and mark its @Component
- In AuthenticationProviderImpl don't forget to check the password through the passport-encoder-bean, but not just through row.equal(income) method
- While user creating don't forget and encode passwords
- In this part we will connect our "Security" with "Data Base" via JdbcUserDetailsManager
For implementation, we will need
- Database driver and SpringJDBC dep
- Create DDL (schema.sql) and DML(data.sql) files in /resources
- Configure app.prop
- Implements CustomJDBCManager and run.
In fact, overriding the set... methods is not necessary. This should be done if the column names in your DB do not match the names username password enabled, authority We can just write that
@Bean
UserDetailsService userDetailsService(DataSource dataSource){
return new JdbcUserDetailsManager(dataSource);
}
- csrf-understanding
CSRF tokens work well in an architecture where the same server is responsible for both the frontend and the backend, mainly for its simplicity. But CSRF tokens don’t work well when the client is independent of the backend solution it consumes.
So this version demonstrates the work of csrf on such architecture.
if we don't send the token we'll get 403, because the server received the form data without a token
And 200 otherwise
CORS - browser protection mitigation. Since the browser does not allow making a request to another Origin, we can change this with CORS.
Origin is the name-fact that the computer is unique, that is, its protocol domain and port are unique if they are the same for two origins, then two origins are the same.
Let's start from the beginning: what happens when you make a cross-origin call if you haven't configured CORS in your application? When an application makes a request, it expects the response to have an Access-Control-Allow-Origin header containing the origins accepted by the server. If this doesn't happen, as is the case with Spring Security's default behavior, the browser won't accept the response
For simple requests, the browser sends the original request directly to the server. The browser rejects the response if the server doesn't allow the origin. In some cases, the browser sends a preflight request to check if the server accepts the origin. If the preflight request is successful, the browser sends the original request