HTTP Basic Auth HTTP Basic Auth HTTP Basic Auth HTTP Basic Auth Basic Auth is the simplest authentication method used with RESTful apis. You only need to provide a user name and password. However, it is less and less used in production environments due to the risk of exposing the user name and password to third-party clients. Therefore, HTTP Basic Auth should be avoided when developing RESTful apis that are open to the outside world

OAuth OAuth (Open authorization) is an open authorization standard that allows a user to allow third-party applications to access the user’s private resources (such as photos, videos, and contact lists) stored on a Web service without having to provide the user name and password to the third-party applications.

OAuth allows users to provide a token, rather than a username and password, to access the data they store with a particular service provider. Each token grants a specific third-party system (for example, a video editing site) access to a specific resource (for example, just a video in a photo album) for a specific period of time (for example, the next 2 hours). In this way, OAuth allows users to authorize third-party sites to access specific information they store with another service provider, but not all of it. Here’s how OAuth2.0 works:

This oAUth-based authentication mechanism is suitable for Internet products of individual consumers, such as social apps, but it is not suitable for enterprise applications with their own authentication permission management.

Cookie Auth Creates a Session object on the server and a Cookie object on the browser of the client for a request authentication. State management is implemented by bringing up Cookie objects from the client to match session objects from the server. By default, cookies are deleted when we close the browser. However, you can modify the expire time of cookies to make them valid for a certain period of time.

Token Auth

What are the advantages of Token Auth over cookies?

Cross-domain access: Cookies do not allow cross-domain access, which does not exist for the Token mechanism, provided that the user authentication information is transmitted through HTTP headers. Stateless (also called server extensible line): The Token mechanism does not need to store session information on the server, because the Token itself contains information about all login users. The status information only needs to be stored in the cookie or local media of the client. More suitable for CDN: you can request all the data (javascript, HTML, images, etc.) from your server via content distribution network, as long as your server provides the API. Decoupling: There is no need to bind to a specific authentication scheme. Tokens can be generated anywhere, as long as you can make Token generation calls when your API is called. More suitable for mobile applications: When your client is a native platform (iOS, Android, Windows 8, etc.), cookies are not supported (you need to use Cookie containers for processing), then Token authentication is much easier. CSRF: Because you no longer rely on cookies, you don’t need to worry about defending against CSRF (cross-site request forgery). Performance: A network round-trip time (query session information from the database) is always much more time-consuming than a Token verification and resolution of HMACSHA256 calculation. No special handling for the login page: If you are functional testing with the Protractor, there is no special handling for the login page. Standardisation based: Your API can use standardised JSON Web tokens (JWT). The standard already exists in several back-end libraries (.NET, Ruby, Java,Python, PHP) and is supported by several companies (e.g. Firebase,Google, Microsoft). JWT based Token authentication mechanism implementing JSON Web Token (JWT) is a very lightweight specification. This specification allows us to use JWT to deliver secure and reliable information between the user and the server. its

Composition of JWT A JWT is essentially a string made up of three parts, a header, a payload, and a signature. Payload

{ “iss”: “Online JWT Builder”, “iat”: 1416797419, “exp”: 1448333419, “aud”: “www.example.com”, “sub”: “[email protected]”, “GivenName”: “Johnny”, “Surname”: “Rocket”, “Email”: “[email protected]”, “Role”: [“Manager”, “Project Administrator”]} iss: the issuer of this JWT, whether to use it is optional; Sub: The JWT is optional for the user. Aud: The party receiving the JWT, whether to use it or not is optional; Exp (Expires): When expires, here is a Unix timestamp, which is optional; Iat (Issued at): When issued (UNIX time), use optional; NBF (Not Before) : If the current time is Before the time in the NBF, the Token is Not accepted. There is usually some leeway, like a few minutes; , whether to use is optional; Base64 encoding the above JSON object yields the following string. And this string we’re going to call the Payload of JWT.

eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9j A2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9 little knowledge: Base64 is a kind of based on 64 printable characters to represent binary data. Since 2 to the sixth power is equal to 64, every six bits is a cell corresponding to some printable character. Three bytes have 24 bits, corresponding to four Base64 units, that is, three bytes need to be represented by four printable characters. JDK provides a very convenient BASE64Encoder and BASE64Decoder, with them can be very convenient to complete base64-based coding and decoding

A JWT also needs a Header that describes the most basic information about the JWT, such as its type and the algorithm used to sign it. This can also be represented as a JSON object.

{” TYP “: “JWT”, “ALG “: “HS256”} specifies in the header that the signature algorithm is HS256. Of course, the header is also BASE64 encoded, and the encoded string is as follows:

EyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 Signature (Signature) of the above two encoded string with a period. Joined together (head first), they form:

EyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0 last, we use strings that will be joining together the above HS256 encrypt algorithm. When encrypting, we also need to provide a secret. If we use MyStar as the key, we can get our encrypted content:

RSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM finally will sign this part also stitching at the back of the string being signed, we get the complete JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7 ItqpKViM will carry this JWT string in our request URL:

Your.awesome-app.com/make-friend… Here is an example of how to implement authentication using JWT:

First Login Authentication: After the first Login, the user enters the user name and password from the browser and submits the password to the Login Action layer of the server. Login Action Invokes the authentication service to authenticate the user name and password. If the authentication succeeds, the Login Action layer invokes the user information service to obtain user information (including complete user information and corresponding permission information). After the user information is returned, the Login Action obtains the key information generated by the Token signature from the configuration file and generates the Token. During Token generation, JWT Lib of the third party can be invoked to generate JWT data after signature. After completing the JWT data signature, it is set into the COOKIE object and redirected to the home page to complete the login process.

Request authentication The token-based authentication mechanism carries the signed Token information in each request. The Token information may be in the COOKIE or HTTP Authorization header.

A client (APP client or browser) makes a GET or POST request to access a resource (page or API); Authentication services act as a Middleware HOOK to intercept requests, first looking for Token information in cookies or, if not found, in the HTTP Authorization Head. If the Token information is found, JWT Lib is called to decrypt and decode the Token information according to the signature encryption key in the configuration file. After the decoding is complete and the signature is verified, the exp, NBF, and AUD information in the Token is verified. After the permission is passed, the permission of the requested resource is determined logically based on the obtained user role permission information. If the permission logic passes, the Response object is returned. Otherwise, HTTP 401 is returned; The Token authentication mechanism has five points of direct attention:

A Token is a collection of information; Include enough information in the Token to reduce the chance of querying the database on subsequent requests; The server needs to check the Token information of the cookie and HTTP Authrorization Header. Based on the previous point, you can use a set of token authentication code for both browser and non-browser clients. Since the token is signed, we can assume that a token that can be decoded and authenticated is issued by our system, and the information contained in it is legal and valid. JAVA implementation of JWT Support in JAVA can be considered using the JJWT open source library; JJWT implements the JWT, JWS, JWE, and JWA RFC specifications; The following provides a simple example to illustrate how to use the Token: Generate the Token code

import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.security.Key; import io.jsonwebtoken.*; import java.util.Date;

//Sample method to construct a JWT

private String createJWT(String id, String issuer, String subject, long ttlMillis) {

//The JWT signature algorithm we will be using to sign the token SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis);

//We will sign our JWT with our ApiKey secret byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKey.getSecret()); Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

//Let’s set the JWT Claims JwtBuilder builder = Jwts.builder().setId(id) .setIssuedAt(now) .setSubject(subject) .setIssuer(issuer) .signWith(signatureAlgorithm, signingKey);

//if it has been specified, let’s add the expiration if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis; Date exp = new Date(expMillis); builder.setExpiration(exp); }

//Builds the JWT and serializes it to a compact, URL-safe string return builder.compact(); } Decodes and validates Token codes

import javax.xml.bind.DatatypeConverter; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Claims;

//Sample method to validate and read the JWT private void parseJWT(String jwt) { //This line will throw an exception if it is not a signed JWS (as expected) Claims claims = Jwts.parser()

.setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret())) .parseClaimsJws(jwt).getBody(); System.out.println(“ID: ” + claims.getId()); System.out.println(“Subject: ” + claims.getSubject()); System.out.println(“Issuer: ” + claims.getIssuer()); System.out.println(“Expiration: ” + claims.getExpiration()); }

Jwt-based Token authentication How to ensure the security of the user name/password authentication? During authentication, a user needs to enter a user name and password. During this process, sensitive information such as the user name and password needs to be transmitted over the network. Therefore, you are advised to use HTTPS to encrypt transmission over SSL to ensure channel security.

Precautions Against XSS Attacks The browser can do many things, which also bring many risks to the security of the browser. The most common ones are: XSS Attacks: Cross Site Scripting; If a page has an input field that allows any information to be entered, and no precautions are taken, if we enter the following code:

This code will steal all the cookies in your domain and send them to hackmeplz.com; So how do we protect against this kind of attack?

XSS attack code filtering removes any code that will cause the browser to do unexpected execution. This can be implemented using several libraries (such as JS-XSS under JS, XSS HTMLFilter under JAVA, TWIG under PHP). If you are storing user-submitted strings in the database (also against SQL injection attacks), you need to do filtering on both the front-end and server side. Http-only Cookies Set the Cookie parameters: HttpOnly; Secure to prevent access to cookies through JavaScript; How do I set cookies to HttpOnly in Java? Servlet 2.5 API does not support cookies set HttpOnly docs.oracle.com/cd/E17802_0… Recommend upgrading Tomcat7.0, which already implements Servlet3.0 tomcat.apache.org/tomcat-7.0-… // Set cookie response.addHeader(” set-cookie “, “uid=112; Path=/; HttpOnly”);

Response. addHeader(” set-cookie “, “uid=112; Path=/; HttpOnly”); response.addHeader(“Set-Cookie”, “timeout=30; Path=/test; HttpOnly”);

Response. addHeader(” set-cookie “, “uid=112; Path=/; Secure; HttpOnly”);

In practice, we can make FireCookie see if the Cookie we set is HttpOnly;

How to Prevent Replay Attacks An attacker sends a received packet to the target host to cheat the system. This attack is mainly used for identity authentication. For example, the Token obtained through user name/password authentication on the browser is stolen by a Trojan horse. Even if the user logs out of the system, the hacker can still use the stolen Token to simulate a normal request, and the server has no idea that the JWT mechanism is stateless. In this case, there are several common practices that can be used as reference: 1. The client and server need to know the timestamp + shared key scheme:

User ID Shared key client

Auth_header = jwt. encode({user_id: 123, iAT: time.now. to_i, # Time.now. to_I + 2 # Specifies the token expiration Time to be 2 seconds later. 2 seconds is enough for an HTTP request and ensures the expiration of the last token to some extent, reducing the probability of replay attacks. }, “”) RestClient.get(“api.example.com/”, authorization: auth_header)

The service side

class ApiController < ActionController::Base attr_reader :current_user before_action :set_current_user_from_jwt_token

Def set_current_user_from_jwt_token # Step 1: decode JWT and get User ID # The signature. Note JWT tokens are not encrypted. but signed. payload = JWT.decode(request.authorization, nil, false)

@current_user = user.find (payload['user_id']) # Step 3: check whether the Token signature is correct JWT.decode(request.authorization, current_user.api_secret) # Step 4: Check "iat" and "exp" to ensure that the Token is created in 2 seconds. Now = Time. Now the to_i if content [' iat] > now | | content [' exp '] < # now if it returns 401 end dateCopy the code

Rescue JWT::DecodeError # return 401 end end

Timestamp + shared key + blacklist (similar to Zendesk) client

Auth_header = jwt.encode ({user_id: 123, jti: rand(2 << 64).to_s, # Time.now.to_i, # specifies the token release Time. Exp: Time.now. to_I + 2 # Specify token expiration Time after 2 seconds}, “”) restClient.get (“api.example.com/”, authorization: auth_header) server

def set_current_user_from_jwt_token

Refer to above for the previous steps

payload = JWT.decode(request.authorization, nil, false) @current_user = User.find(payload[‘user_id’]) JWT.decode(request.authorization, Current_user. Api_secret) now = Time. Now. To_i if content [‘ iat] > now | | content [‘ exp ‘] < # now return to the end of 401

Let’s check to make sure this JWT has not been used before

Atomic operations using Redis

The redis key…

key = “#{payload[‘user_id’]}:#{payload[‘jti’]}”

See if the key value already exists in Redis. Return nil if it does not exist. Return “1” if it does.

If redis.getSet (key, “1”) # return 401 # end

Perform key expiration checks

redis.expireat(key, payload[‘exp’] + 2) end

This section describes how to prevent MAN-in-the-middle (MITM) Attacks. MITM Attacks are monitored during The interaction between The client and server, for example, The WIFI of a cafe with Internet access is monitored or proxy servers are hacked. HTTPS is used against such attacks, including for distributed applications and for transferring sensitive information such as cookies between services. So cloud computing is inherently insecure.