Basic authentication and digest authentication are very popular as alternative authentication mechanisms in web applications. Among them, basic authentication is often used to authenticate stateless clients. For example, in combination with the form-based authentication form, we can provide authentication to users who access through browsers and users who access through web-service (restful). Because the user name and password are sent to the server in text form during basic authentication, in applications with high security levels, basic authentication needs to be encrypted during transmission, for example, in the form of https.
1. Basic Authentication
1. Filter BasicAuthenticationFilter
The logic related to basic authentication is mainly in this filter. When the filter receives a request, it is executed according to the following logic
HTTP/1.1 401 X-Content-Type-Options nosniff X-XSS-Protection 1; mode=block Cache-Control no-cache, no-store, max-age=0, must-revalidate Pragma no-cache Expires 0 X-Frame-Options DENY Set-Cookie JSESSIONID=493B4D42EC4A2D5AA85C7521288F54F9; Path=/; HttpOnly WWW-Authenticate Basic realm="Realm" Content-Type text/html;charset=ISO-8859-1 Content-Language zh-CN Content-Length 344 Date Tue, 06 Mar 2018 01:42:28 GMT Proxy-Connection Keep-alive
After the browser receives the information, a pop-up box prompts the user to enter the username and password, and then the browser encodes the username and password and sends it to the server, for example:
GET /index.html HTTP/1.1 Host localhost:8080 Cache-Control max-age=0 Authorization Basic dXNlcjpwYXNzd29yZA== Upgrade-Insecure-Requests 1 User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 Accept text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding gzip, deflate, br Accept-Language zh-CN,zh;q=0.9,en;q=0.8 Cookie JSESSIONID=493B4D42EC4A2D5AA85C7521288F54F9
[dXNlcjpwYXNzd29yZA==] The corresponding value is the encrypted information of the user name and password.
The authentication process is as follows:
2. From the above content, we can see that the authentication logic of this authentication method is very simple, and the developer does not need to consider how the login page is displayed, and the development method is very simple. However, using this authentication method, the request header information is transmitted in clear code during the transmission process. The user name and password encryption method used is BASE-64. The decoding process is very simple. It is cracked, so its authentication technology is not very secure. Generally, it is used on embedded devices. In practical applications, it is best to combine the TLS technology to encrypt the transmitted information to improve security.
3. It is also very simple to enable basic authentication in the spring boot application
@Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .disable() .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); }
You can call the httpBasic() method of HttpSecurity. How to add BasicAuthenticationFilter to the servletContext for this method can be found in the previous article. The explanation of the core filter is not expanded here.
2. Digest authentication
1. Digest authentication is mainly to solve the problem that the password is easy to be cracked in the basic authentication, and to improve the security by encrypting the authentication information. It is best not to consider using digest authentication in enterprise-level application development. It only improves the security of basic authentication, but there are still security holes. The most obvious problem is that you have to save the password in one of clear text, encoded, MD5 processed, and these algorithms are all reversible algorithms, so they are all insecure. Instead, we should use a unidirectional hash algorithm (bCrypt, PBKDF2, SCrypt) to protect our passwords. This authentication method should be considered only when a more secure authentication method cannot be used under the constraints of some external factors. 2. The core of digest authentication is an incomprehensible character-"nonce" generated by the server, which is generated by the following algorithm
base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) expirationTime: The point in time at which the nonce expires, in milliseconds key: a private key to prevent the nonce from being modified
Because the client has been encrypted when passing the user credentials to the server, and the password information cannot be recovered, so we must take the original password and go through the same hash algorithm to get the result and then compare it with the client's result, which is why we The reason why the user password must be stored in clear text .
3. The logic related to DigestAuthenticationFilter
and digest authentication are all in this Filter. The main processing logic is as follows:
HTTP/1.1 401 X-Content-Type-Options nosniff X-XSS-Protection 1; mode=block Cache-Control no-cache, no-store, max-age=0, must-revalidate Pragma no-cache Expires 0 X-Frame-Options DENY Set-Cookie JSESSIONID=AE5A3F9F3ED75248B801954C58850A39; Path=/; HttpOnly WWW-Authenticate Digest realm="security", qop="auth", nonce="MTUyMDMyMjk3NDIzOTpjOGZiMzYyY2MzNTQ1ZGQwN2UwNzE1YzE2YjExNWQwMg==" Content-Type text/html;charset=ISO-8859-1 Content-Language zh-CN Content-Length 344 Date Tue, 06 Mar 2018 07:51:14 GMT Proxy-Connection Keep-alive
After that, the browser pop-up box prompts the user to enter the username and password, and then the browser encodes the username and password and sends it to the server
GET /index.html HTTP/1.1 Host localhost:8080 Cache-Control max-age=0 Authorization Digest username="user", realm="security", nonce="MTUyMDMyMjk3NDIzOTpjOGZiMzYyY2MzNTQ1ZGQwN2UwNzE1YzE2YjExNWQwMg==", uri="/index.html", response="87007805d864a0f07f0bbf0e915fbe68", qop=auth, nc=00000001, cnonce="645f7f377909cc62" Upgrade-Insecure-Requests 1 User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 Accept text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding gzip, deflate, br Accept-Language zh-CN,zh;q=0.9,en;q=0.8 Cookie JSESSIONID=AE5A3F9F3ED75248B801954C58850A39
The authentication flow chart is the same as basic authentication, the only difference is that Filter is replaced by DigestAuthenticationFilter, and the process is no longer drawn here.
4. Configure the degist authentication method in spring boot
@Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .disable() .authorizeRequests() .anyRequest().authenticated() .and() .exceptionHandling() .authenticationEntryPoint(digestEntryPoint()).and() .addFilter(digestFilter()); } @Bean public DigestAuthenticationEntryPoint digestEntryPoint() { DigestAuthenticationEntryPoint entryPoint = new DigestAuthenticationEntryPoint(); entryPoint.setKey("chengf"); entryPoint.setRealmName("security"); return entryPoint; } @Bean public DigestAuthenticationFilter digestFilter() throws Exception { DigestAuthenticationFilter digestFilter = new DigestAuthenticationFilter(); digestFilter.setAuthenticationEntryPoint(digestEntryPoint()); digestFilter.setUserDetailsService(userDetailsService()); return digestFilter; }
Complete sample code reference: source code