DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Develop a Spring Boot REST API in AWS: PART 4 (CodePipeline / CI/CD)
  • Aggregating REST APIs Calls Using Apache Camel
  • Leveraging Salesforce Using Spring Boot
  • Spring Boot REST API Request Body Validation Example Using a Custom Validator

Trending

  • When Angular APIs Return 200 but the Frontend Is Already Failing Users
  • Production Database Migration or Modernization: A Comprehensive Planning Guide [Part 2]
  • The Invisible OOMKill: Why Your Java Pod Keeps Restarting in Kubernetes
  • How Retry Storms Crash API-Led Systems: Bounded Reliability Patterns for Distributed Architectures
  1. DZone
  2. Coding
  3. Frameworks
  4. Securing a JSON API REST Service With Spring Boot and Elide

Securing a JSON API REST Service With Spring Boot and Elide

Learn how to make use of the security layer in Elide to make some decisions about who can perform what operation.

By 
Matthew Casperson user avatar
Matthew Casperson
·
Updated May. 16, 16 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
4.9K Views

Join the DZone community and get the full member experience.

Join For Free

In a previous article we saw how to create new entities and how to set the relationships between entities by implementing support for Elide’s post() method. But security restrictions prevented us from actually modifying these relationships.

Now that our API has authentication, we can make use of the security layer in Elide to make some decisions about who can perform what operation.

A quick note here that this article is based on Elide 2.0.1, which fixes up some bugs from the version 1 we were using in previous articles. Specifically, you may have noticed that we were getting security errors in previous articles despite setting the security mode to inactive. This issue is now resolved in Elide 2.

Before we can make use of the security features in Elide, we need to enable security for our endpoints. This is done by passing the SecurityMode.SECURITY_ACTIVE value to the Elide methods get() and post().

So let’s take a look at what “allow all” permissions look like with Elide:

package com.matthewcasperson.elidetest.jpa;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.yahoo.elide.annotation.*;
import com.yahoo.elide.security.checks.prefab.Role;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;


/**
 * The persistent class for the parent database table.
 * 
 */
@ReadPermission(any={Role.ALL.class })
@SharePermission(any={Role.ALL.class })
@CreatePermission(any={Role.ALL.class })
@UpdatePermission(any={Role.ALL.class })
@DeletePermission(any={Role.ALL.class })
@Entity
@Table(name="parent")
@NamedQuery(name="Parent.findAll", query="SELECT p FROM Parent p")
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;

private Integer id;

private String description;

private String name;

private List<Child> children;

public Parent() {
}

@Id
@Column(unique=true, nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return this.id;
}

public void setId(int id) {
this.id = id;
}

@Column(length=45)
public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

@Column(length=45)
public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

//bi-directional many-to-one association to Child
@OneToMany(mappedBy="parent")
@JsonManagedReference
public List<Child> getChildren() {
return this.children;
}

public void setChildren(List<Child> childs) {
this.children = childs;
}

public Child addChild(Child child) {
getChildren().add(child);
child.setParent(this);

return child;
}

public Child removeChild(Child child) {
getChildren().remove(child);
child.setParent(null);

return child;
}

}


Permissions in Elide are assigned through the annotations @CreatePermission, @ReadPermission, @UpdatePermission and @DeletePermission, which map to the common CRUD operations that you’ll perform when interacting with any database. These annotations are assigned to the JPA entities. In addition to these four CRUD permission annotations, there is also a @SharePermission annotation which is used to determine if entities can be related to one another.

All these permission annotations take an array of classes assigned to the any or all parameters. As you would expect, all checks assigned to the all parameter must pass for the operation to succeed, while one or more of the checks assigned to the any parameter must pass for the operation to succeed.

The Role.ALL.class is provided by the Elide library to always permit the operation.

With the five annotations above applied to each of the JPA entities, and with each annotation having a Role.ALL.class assigned to the any parameter, we are now free to perform any action supported by the Elide library. Now, when we POST

{
  "data": { "type": "child", "id": "1" }
}


to http://localhost:8080/parent/2/relationships/children, we see that the child with the ID of 1 is assigned to the parent with the ID of 2.

If you want to achieve the reverse, and deny anyone from doing anything with the API, you can use the Role.NONE.class.

@ReadPermission(any={Role.NONE.class })
@SharePermission(any={Role.NONE.class })
@CreatePermission(any={Role.NONE.class })
@UpdatePermission(any={Role.NONE.class })
@DeletePermission(any={Role.NONE.class })


Now, the same POST operation results in the following response:

{
  "errors": [
    "ForbiddenAccessException"
  ]
}


Obviously a blanket “deny all” security policy is quite useless in real life, but by mixing and matching the Role.ALL.class and Role.NONE.class with the various operations provided by Elide, it is possible to customize the access to your entities via your API.

In the next article, we’ll look at creating customized permission checks to provide even more fine-grained access based on user roles.

Download the source code for this article from here.

API Spring Framework JSON REST Web Protocols Spring Boot

Opinions expressed by DZone contributors are their own.

Related

  • Develop a Spring Boot REST API in AWS: PART 4 (CodePipeline / CI/CD)
  • Aggregating REST APIs Calls Using Apache Camel
  • Leveraging Salesforce Using Spring Boot
  • Spring Boot REST API Request Body Validation Example Using a Custom Validator

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook