play-rest-security

repository·master·Indexed 19 days ago

https://github.com/jamesward/play-rest-security

A reference implementation for securing Single Page Applications (SPAs) and RESTful services using the Play Framework. It demonstrates a pattern to prevent CSRF attacks by replacing cookie-based authentication with custom HTTP headers for token transmission, utilizing Java, JPA, jQuery, and CoffeeScript.

Tokens
950
Snippets
2
Records
5
Agent score
15%

What's inside play-rest-security

  1. How to secure Single Page Apps (SPA) against CSRF

    master

    To avoid Cross-Site Request Forgery (CSRF) vulnerabilities, avoid using cookies as the sole method for identifying a user on the server. Instead, use a custom HTTP header to pass an authentication token.

    The Recommended Workflow:

    1. Initial Load: The server returns the web page and JavaScript application.
    2. Token Retrieval: The JavaScript application reads the authentication token from a cookie (which is safe because malicious sites cannot access your domain's cookies via JS).
    3. Authenticated Requests: For every subsequent request to protected data, the JavaScript application manually includes that token in a custom HTTP header.
    4. Server Validation: The server validates the user based on the token in the custom header rather than the cookie itself.
    5. Error Handling: If the server returns a 401 (Unauthorized) response, the JavaScript application should trigger the login flow.

    Security Note: Always use HTTPS to ensure tokens are encrypted in transit. Configure your cookies to only be sent over HTTPS to prevent accidental transmission over unencrypted connections.

  2. Run the sample application locally

    master

    The sample application is built using the Play Framework, Java, jQuery, and CoffeeScript. To run it locally:

    1. Download and extract the latest Typesafe Activator.
    2. Add the activator directory to your system's PATH.
    3. Navigate to the play-rest-security directory in your terminal.
    4. Run the application using the activator run command.

    The application will be available at http://localhost:9000/.

    activator run
  3. Implement a secured RESTful Back-End with Play and JPA

    master

    The sample application demonstrates a pattern for securing RESTful JSON services using the Play Framework and JPA.

    Data Model

    Entities like User.java should include an authToken property to store the authentication token. In production, consider supporting multiple tokens per user (to allow multiple concurrent sessions) and encrypting tokens in the database.

    Securing Controllers

    To protect controller methods, use the @Security.Authenticated annotation. This utilizes action composition to trigger a security check.

    Authentication Logic

    1. Token Lookup: A security class (e.g., Secured.java) implements a getUsername method. This method extracts the token from the custom HTTP header and looks up the corresponding user.
    2. Access Control: If the user is found, the username is stored in the HTTP Context for use in the controller. If not found, the method returns null, the request is blocked, and an onUnauthorized handler (e.g., returning a redirect or 401) is triggered.
    3. Login/Logout:
      • login: Validates credentials, generates a new authToken, sets it in a cookie, and returns the token in a JSON response.
      • logout: Validates the user via an interceptor, deletes the authentication cookie, and nullifies the authToken in the database.
  4. Implement a CoffeeScript and jQuery Front-End UI

    master

    The front-end manages authentication state and communicates with the REST API using custom headers.

    Authentication Flow in JavaScript

    1. Initialization: On page load, the application checks for an authentication token in the browser's cookies.
    2. Conditional UI:
      • If no token is found: Display a login form.
      • If a token is found: Proceed to fetch data.
    3. Making Authenticated Ajax Requests: When calling protected endpoints (e.g., getAllTodos or createTodo), the application must manually include the authentication token in a custom HTTP header within the Ajax request.
    4. Handling Unauthorized Access: If an Ajax request returns a 401 error, the application must clear the local state and display the login form again.