When asking this question I am looking for guidance with implementation of my own AuthenticationProvider. By that I mean the following:
Till now I have learned that Spring Security ask the AuthenticationProvider object if the user is authenticated or not. Currently I am using the DaoAuthenticationProvider which process the username and the password that is being returned by my own custom UserDetailService. All works great! Spring support a lot of different AuthenticationProvider's for example there is one for LDAP, Jdbc, DAO (as mentioned above) and i was even able to find one for Kerberos. However there is no authentication provider for SRP, thus the need to write one.
My question is here the following:
When we use the DaoAuthenticationProvider i.e. user/password authentication, we have a html form where the username and password are entered and then a button is responsible for submitting those 2 parameters. Both parameters are transferred over some transport channel to the server i.e. with one click we are able to send all of the data within the same http request i.e. all that is needed for the authentication. That can be seen in the UsernamePasswordAuthenticationFilter. Here the method "attemptAuthentication" takes "HttpServletRequest request" which includes username and password. Till now all good.
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
...
}
Well, in the simple in SRP we have also a form that has a username and password, except the password !!!MUST!!! not be transferred over the network. In order to achieve that constrain a "discussion" between the client and the server has to take place i.e. the following parameters must be exchanged.
username (I),
a value called "A"
a value called "B"
a value called "M1"
a value called "M2"
Well, let us assume that there is a filter called "SrpAuthenticationProcessingFilter" how should the filter look like if the new authentication protocol was more like a conversation by that I mean from the RFC 5054.
Client Server
Client Hello (I) -------->
Server Hello
Certificate*
Server Key Exchange (N, g, s, B)
<-------- Server Hello Done
Client Key Exchange (A) -------->
[Change cipher spec]
Finished -------->
[Change cipher spec]
<-------- Finished
Application Data <-------> Application Data
Here we have a client that needs to
- a) send first his username (I)
- b) then the server needs to respond with a value B. (N,g,s are not really necessary in this case)
- c) the client sends it's "value A"
- d) the the client uses that value B from the server and based on that value calculates a key.
- e) the server calculates the key as well based on the value A.
- f) the client sends value M1 to the server.
- g) the server gets the M1 value and based on a formula which has the M1 value as argument, he is able to verify if the keys match, if the calculated keys of the bought sides match then the user is authenticated, and the product i.e. the shared key could be used further for other processing.
In a contrast to username and password authentication those are 7 steps not one. And 3 of those needs to happen before the SrpAuthenticationProcessingFilter. Now I am aware that there is a possibility to send the username together with the "value A" thus shortening the number of steps, but I would like to strictly follow the RFC. Never take the easy way right?
The question really is where do I place that code which is responsible for the ping pong (conversation) between the client and the server i.e. the first 3 steps a, b and c mentioned above. Should it place them in a SrpEntryPoint object, or somewhere else. if else then were in the context of SpringSecurity?
One way I can thing of solving this is using websockets, but I would also like to make that authentication independent from any layer 5-7 protocol such as websockets, http, spdy etc. . That means that the first implementation should be be through simple http request/response and then with any other protocol.
So the structure that could be the right one in order to implement SRP currently is:
SRPAuthenticationEntryPoint implements org.springframework.security.web.AuthenticationEntryPoint - this basically says what should be done if a request for a protected resource gets in, but the user is not authenticated yet. Here we can place a redirect in the case the resource has not been authenticated. Maybe this is also the place which is responsible for the steps a,b,c not sure if that is the right place. Request guidance and information!!
SrpAuthenticationProcessingFilter extends GenericFilterBean. SrpAuthenticationProcessingFilter exists to make partial validation for example to check if the srp parameters received a correct and corresponding to the srp parameters that the server sets. Here it is important to mention that SrpAuthenticationProcessingFilter is not doing any username validation i.e. that needs to happen in one step before the SrpAuthenticationProcessingFilter is being called, maybe that is the SrpEntryPoint or some other step that I do not know how to call it yet. SrpAuthenticationProcessingFilter has a method "doFilter" in which the second structure is being created i.e. SrpAuthenticationToken.
SrpAuthenticationToken extend org.springframework.security.authentication.AbstractAuthenticationToken. That token in my understanding is something similar to the DAO object, the token maps all field needed for successful authentication. When partially validated parameters are populated into the SrpAuthenticationToken that SrpAuthenticationToken is passed to the authenticate method of the org.springframework.security.authentication.AuthenticationManager interface i.e. something like that
myAuthentication = authenticationManager.authenticate(SrpAuthenticationToken);
depending on which Authentication Provider is configured in the Spring Security config then the SrpAuthentication provider is called in our case i.e.:
@Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(sRPAuthenticationProvider);
}
SRPAuthenticationProvider - implements org.springframework.security.authentication.AuthenticationProvider. Over here the steps d,e,f and g are being validated and compared. If something wrong happens then throw new BadCredentialsException("Invalid username/password/Verifiere") exception.
SrpSessionValidator - this one is responsible only for validating particular parameters of the Srp session and would be called from SrpAuthenticationProcessingFilter as well as in one step before the SrpAuthenticationProcessingFilter in order to validate if the username exists in the database at all.
I only have a general idea how to implement that Srp authentication, and thus I would like some comments if that makes sense at all and if SRPAuthenticationEntryPoint is the right place for the steps a,b and c. It does not feel like the right place to me.
Any feedback is greatly appreciated.
Addition1 (21 November 2014) -> As an answer to the question "where to place that code which is responsible for the ping pong (conversation) between the client and the server i.e. the first 3 steps a,b and c " the answer to that would be most likely a standard (I will call it negotiation) filter which will take that job.
Now I would like to rephrase the question i.e. before the authentication is complete and before the M1 and M2 messages are received i.e. steps 1 2 and 3. Where do I place that object? I.e. it should be a place where the object should live for example for 60 seconds and then be automatically deleted in case no M1 and M2 messages has been received. I mean some object before the "SecurityContextHolder" object. I just do not know what is the name of that object/context related to spring security, also I do not know if such construct exists at all?