CÔNG NGHỆ THÔNG TIN >> BÀI VIẾT CHỌN LỌC

Security trong Restful Webservice sử dụng Jersey 2 để sinh ra JWT

Đăng lúc: 07:24 PM - 29/11/2023 bởi Charles Chung - 1023

Trong bài viết này tôi sẽ hướng dẫn các bạn cách bảo mật Restful Webservice, chúng ta sẽ sử dụng thư viện Jersey 2 để sinh ra JWT Bearer, cơ sở dữ liệu sử dụng Oracle, truy xuất dữ liệu sử dụng Hibernate

Giới thiệu Token-based Authentication

JSON Web Token (JWT) là 1 tiêu chuẩn mở (RFC 7519), định nghĩa cách thức truyền tin an toàn giữa các ứng dụng bằng một đối tượng JSON. Dữ liệu truyền đi sẽ được mã hóa và chứng thực, có thể được giải mã để lấy lại thông tin và đánh dấu tin cậy nhờ vào “chữ ký” của nó. Phần chữ ký của JWT sẽ được mã hóa lại bằng HMAC hoặc RSA. Chi tiết các bạn xem lại bài viết “Giới thiệu Json Web Token (JWT)“.

Token-based Authentication là cơ chế xác thực người dùng dựa trên việc tạo ra token – một chuỗi ký tự (thường được mã hóa) mang thông tin xác định người dùng được server tạo ra và lưu ở client. Server sau đó có thể không lưu lại token này.

Token-based Authentication trong Jersey 2.x

Mô tả yêu cầu:

  • Tạo Restful Webservice "StudentService" cung cấp các method GET, POST, PUT, DELETE để thao tác dữ liệu với bảng Student (xem cấu trúc trong hình dưới). Áp dụng cơ chế bảo mật cho các method trong Rest Webservice bằng cách sử dụng Token để xác thực người dùng khi truy cập vào StudentService, tài khoản người dùng sẽ được gán ROLE rõ ràng (role gồm 2 loại ADMIN và STUDENT), apply ROLE cho các method để kiểm thử.
  • Cơ sở dữ liệu sử dụng Oracle.
  • Mật khẩu sử dụng MD5 mã hóa.
  • Truy xuất dữ liệu sử dụng Hibernate.

Giải pháp

Bước 1: Tạo cơ sở dữ liệu có tên "bkap" trong oracle với các bảng mô tả như sau:

Dữ liệu mẫu xem trong file bkap_jwt.sql trong source đính kèm

Bước 2: Tạo Dynamic Web Project (xem chi tiết bài Phát triển ứng dụng RESTful Web Service trong Java với thư viện Jersey )

  • Khởi động Eclispe IDE -> vào menu File -> New -> Dynamic Web Project -> Nhập tên "RestfulWebServiceJWT"
  • Tiêp tục kích vào Next -> Next -> Chọn Generate web.xml deyployment desciptor 

Bước 3: Convert sang Maven Project

  • Kích chuột phải vào Project vừa tạo -> Configure -> Convert to Maven Project -> Finish

Bước 4: Khai báo các Maven Dependencies cần thiết

  • Mở file pom.xml và cấu hình các Maven Dependencies gồm: jersey server 2, gson, hibernate, oracle, jaxb api, jsonwebtoken,..

<dependencies>

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-core</artifactId>

<version>5.4.26.Final</version>

</dependency>

<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc10 -->

<dependency>

<groupId>com.oracle.database.jdbc</groupId>

<artifactId>ojdbc10</artifactId>

<version>19.20.0.0</version>

</dependency>

<dependency>

<groupId>org.glassfish.jersey.containers</groupId>

<artifactId>jersey-container-servlet</artifactId>

<version>2.41</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-server -->

<dependency>

<groupId>org.glassfish.jersey.core</groupId>

<artifactId>jersey-server</artifactId>

<version>2.41</version>

</dependency>

<dependency>

<groupId>org.glassfish.jersey.inject</groupId>

<artifactId>jersey-hk2</artifactId>

<version>2.41</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->

<dependency>

<groupId>org.glassfish.jersey.media</groupId>

<artifactId>jersey-media-json-jackson</artifactId>

<version>2.41</version>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-api</artifactId>

<version>0.10.5</version>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-impl</artifactId>

<version>0.10.5</version>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt-jackson</artifactId>

<version>0.10.5</version>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>javax.xml.bind</groupId>

<artifactId>jaxb-api</artifactId>

<version>2.3.1</version>

</dependency>

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->

<dependency>

<groupId>com.google.code.gson</groupId>

<artifactId>gson</artifactId>

<version>2.10.1</version>

</dependency>

</dependencies>

Bước 5: Cấu hình ứng dụng Jersey Servlet

  • Mở tệp web.xml và cấu hình vào bên trong thẻ <web-app> như sau:

<servlet>

<servlet-name>jersey2Serlvet</servlet-name>

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>hanam88.api</param-value>

</init-param>

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>hanam88.api</param-value>

</init-param>

<init-param>

<param-name>jersey.config.server.provider.classnames</param-name>

<param-value>org.glassfish.jersey.filter.LoggingFilter;

org.glassfish.jersey.jackson.JacksonFeature;

hanam88.filter.AuthFilter;

org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>jersey2Serlvet</servlet-name>

<url-pattern>/api/*</url-pattern>

</servlet-mapping>

Bước 6: Tạo các package và các class theo cấu trúc sau

  • Tệp cấu hình hibernate.cfg.xml (cấu hình kết nối cơ sở dữ liệu oracle và hibernate)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:bkap</property>

<property name="hibernate.connection.password">1234$</property>

<property name="hibernate.connection.username">system</property>

<property name="hibernate.show_sql">true</property>

<property name="hibernate.current_session_context_class">thread</property>

<property name="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</property>

<mapping class="hanam88.model.Student" />

<mapping class="hanam88.model.Account" />

<mapping class="hanam88.model.AccountRole" />

<mapping class="hanam88.model.Role" />

</session-factory>

</hibernate-configuration>

 

  • Tạo lớp hanam88.dao\HibernateUtil.java (đọc thông tin cấu hình trong tệp hibernate.cfg.xml và tạo sessionfactory)

public class HibernateUtil {

public static SessionFactory getSessionFactory() {

SessionFactory sf = new Configuration().configure().buildSessionFactory();

return sf;

}

}

  • Tạo lớp hanam88.model\Account.java

@Entity

@Table(name="accounts")

public class Account {

@Id

@Column(name = "accountid")

private String accountid;

@Column(name = "username")

private String userName;

@Column(name = "password")

private String passWord;

@Column(name = "fullname")

private String fullName;

@Column(name = "gender")

private int gender;

@Column(name = "birthday")

@Temporal(value = TemporalType.DATE)

private Date birthday;

@Column(name = "email")

private String email;

@Column(name = "phone")

private String phone;

@Column(name = "avatar")

private String avatar;

@Column(name = "note")

private String note;

@Column(name = "active")

private int active;

@OneToMany(mappedBy = "account", fetch = FetchType.EAGER)

private Set<AccountRole> accountroles;

public Account() {

// TODO Auto-generated constructor stub

}

 

public String getAccountid() {

return accountid;

}

public void setAccountid(String accountid) {

this.accountid = accountid;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassWord() {

return passWord;

}

public void setPassWord(String passWord) {

this.passWord = passWord;

}

public String getFullName() {

return fullName;

}

public void setFullName(String fullName) {

this.fullName = fullName;

}

public int getGender() {

return gender;

}

public void setGender(int gender) {

this.gender = gender;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

public String getAvatar() {

return avatar;

}

public void setAvatar(String avatar) {

this.avatar = avatar;

}

public String getNote() {

return note;

}

public void setNote(String note) {

this.note = note;

}

public int getActive() {

return active;

}

public void setActive(int active) {

this.active = active;

}

public Set<AccountRole> getAccountroles() {

return accountroles;

}

public void setAccountroles(Set<AccountRole> accountroles) {

this.accountroles = accountroles;

}

}

  • Tạo lớp hanam88.model\Role.java

@Entity

@Table(name="roles")

public class Role {

@Id

@Column(name = "roleid")

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = "rolename")

private String rolename;

@OneToMany(mappedBy = "role")

private Set<AccountRole> accountroles;

public Role() {

// TODO Auto-generated constructor stub

}

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getRolename() {

return rolename;

}

public void setRolename(String rolename) {

this.rolename = rolename;

}

public Set<AccountRole> getAccountroles() {

return accountroles;

}

public void setAccountroles(Set<AccountRole> accountroles) {

this.accountroles = accountroles;

}

}

  • Tạo lớp hanam88.model\AccountRole.java

@Entity

@Table(name="accounts_roles")

public class AccountRole {

@Id

@Column(name = "id")

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@ManyToOne

@JoinColumn(name = "accountId")

private Account account;

@ManyToOne

@JoinColumn(name = "roleId")

private Role role;

public AccountRole() {

// TODO Auto-generated constructor stub

}

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public Account getAccount() {

return account;

}

public void setAccount(Account account) {

this.account = account;

}

public Role getRole() {

return role;

}

public void setRole(Role role) {

this.role = role;

}

}

  • Tạo lớp hanam88.model\AccountDetail.java

//Lớp customize Principal để lưu thêm thông tin người dùng

public class AccountDetail implements Principal{

private String username;

private String password;

private String fullName;

private int gender;

private String email;

private String phone;

private String avatar;

private List<String> roles = new ArrayList<>();

public AccountDetail() {

}

public AccountDetail(Account user) {

if (user != null) {

this.username = user.getUserName();

this.password = user.getPassWord();

this.avatar = user.getAvatar();

this.email = user.getEmail();

this.fullName = user.getFullName();

System.out.println(this.fullName);

this.gender = user.getGender();

this.phone = user.getPhone();

var accroles = user.getAccountroles();

for (AccountRole accountRole : accroles) {

this.roles.add(accountRole.getRole().getRolename());

}

}

}

public String getFullName() {

return fullName;

}

public void setFullName(String fullName) {

this.fullName = fullName;

}

public int getGender() {

return gender;

}

public void setGender(int gender) {

this.gender = gender;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

public String getAvatar() {

return avatar;

}

public void setAvatar(String avatar) {

this.avatar = avatar;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public List<String> getRoles() {

return roles;

}

public void setRoles(List<String> roles) {

this.roles = roles;

}

@Override

public String getName() {

return username;

}

}

  • Tạo lớp hanam88.model\Student.java

@Entity

@Table(name = "students")

public class Student {

@Id

private String studentId;

private String fullName;

private int gender;

@Temporal(TemporalType.DATE)

private Date birthDay;

private String email;

private String phone;

private String address;

private int active;

public Student() {

// TODO Auto-generated constructor stub

}

public String getStudentId() {

return studentId;

}

public Student(String studentId, String fullName, int gender, Date birthDay, String email, String phone,

String address, int active) {

super();

this.studentId = studentId;

this.fullName = fullName;

this.gender = gender;

this.birthDay = birthDay;

this.email = email;

this.phone = phone;

this.address = address;

this.active = active;

}

public void setStudentId(String studentId) {

this.studentId = studentId;

}

public String getFullName() {

return fullName;

}

public void setFullName(String fullName) {

this.fullName = fullName;

}

public int getGender() {

return gender;

}

public void setGender(int gender) {

this.gender = gender;

}

public Date getBirthDay() {

return birthDay;

}

public void setBirthDay(Date birthDay) {

this.birthDay = birthDay;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public int getActive() {

return active;

}

public void setActive(int active) {

this.active = active;

}

}

  • Tạo lớp hanam88.model\BasicSecurityContext.java

public class BasicSecurityContext implements SecurityContext {

private AccountDetail user;

private boolean secure;

public BasicSecurityContext(AccountDetail user, boolean secure) {

this.user = user;

this.secure = secure;

}

@Override

public AccountDetail getUserPrincipal() {

return user;

}

@Override

public boolean isUserInRole(String role) {

return user.getRoles().contains(role);

}

@Override

public boolean isSecure() {

return secure;

}

@Override

public String getAuthenticationScheme() {

return SecurityContext.BASIC_AUTH;

}

}

  • Tạo lớp hanam88.dao\AccountDAO.java

public class AccountDAO {

SessionFactory sf = HibernateUtil.getSessionFactory();

//lấy thông tin người dùng theo username

public AccountDetail getUser(String username) {

Session session=sf.openSession();

Account account = (Account) session.createQuery("from Account where username = :username")

.setParameter("username", username).uniqueResult();

session.close();

if(account!=null)

return new AccountDetail(account);

else

return null;

}

}

  • Tạo lớp hanam88.dao\StudentDAO.java

public class StudentDAO {

SessionFactory sf = HibernateUtil.getSessionFactory();

public List<Student> getAll() {

Session session = sf.openSession();

List<Student> data = new ArrayList<>();

Query query = session.createQuery("from Student");

data = query.getResultList();

session.close();

return data;

}

public Student getById(String studentId) {

Session session = sf.openSession();

Student student = session.get(Student.class, studentId);

session.close();

return student;

}

public void insert(Student st) {

Session session = sf.openSession();

session.beginTransaction();

session.save(st);

session.getTransaction().commit();

session.close();

}

public void update(Student st) {

Session session = sf.openSession();

session.beginTransaction();

session.update(st);

session.getTransaction().commit();

session.close();

}

public Student delete(String studentId) {

Session session = sf.openSession();

session.beginTransaction();

Student student = session.get(Student.class, studentId);

if (student != null) {

session.remove(student);

session.getTransaction().commit();

}

session.close();

return student;

}

}

  • Tạo lớp hanam88.helper\MD5Encoder.java

public class MD5Encoder {

public static String GenerateMD5(String data){

try {

// gọi phương thức tạo đối tượng hóa MD5

MessageDigest md = MessageDigest.getInstance("MD5");

//chuyển chuỗi hóa về dạng byte

byte[] messageDigest = md.digest(data.getBytes());

//chuyển mảng byte thành số

BigInteger no = new BigInteger(1, messageDigest);

// convert thành chuỗi hexa 16

String hashtext = no.toString(16);

while (hashtext.length() < 32) {

hashtext = "0" + hashtext;

}

return hashtext;

} catch (NoSuchAlgorithmException ex) {

System.out.println("Sai tên giải thuật");

}

return null;

}

}

  • Tạo lớp hanam88.helper\JwTokenHelper.java

public class JwTokenHelper {

// The privateKey is only valid for the given minutes

private static final long EXPIRATION_LIMIT_IN_MINUTES = 30;

// The JWT signature algorithm we will be using to sign the token

private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;

// Keys used with HS256 MUST have a size >= 256 bits

private static final String SECRET_KEY = "hanam88dotcom-jwt-restful-webservice-with-oracle-example";

private static final String ISSUER = "https://hanam88.com";

private JwTokenHelper() {

super();

}

public static String createJWT(AccountDetail user) {

// Get the current time

long currentTimeInMillis = System.currentTimeMillis();

Date now = new Date(currentTimeInMillis);

// The privateKey is only valid for the next EXPIRATION_LIMIT_IN_MINUTES

long expirationTimeInMilliSeconds = TimeUnit.MINUTES.toMillis(EXPIRATION_LIMIT_IN_MINUTES);

Date expirationDate = new Date(currentTimeInMillis + expirationTimeInMilliSeconds);

// Will sign our JWT with our ApiKey secret

byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);

Key signingKey = new SecretKeySpec(apiKeySecretBytes, SIGNATURE_ALGORITHM.getJcaName());

// Sets the JWT Claims sub (subject) value

Claims claims = Jwts.claims().setSubject(user.getUsername());

//thêm thông tin người dùng vào claims

claims.put("roles", user.getRoles());

claims.put("fullname", user.getFullName());

claims.put("avatar", user.getAvatar());

// Let's set the JWT Claims

JwtBuilder builder = Jwts.builder() // Configured and then used to create JWT compact serialized strings

.setClaims(claims).setId(UUID.randomUUID().toString()) // Sets the JWT Claims jti (JWT ID) value

.setIssuedAt(now) // Sets the JWT Claims iat (issued at) value

.setIssuer(ISSUER) // Sets the JWT Claims iss (issuer) value

.setExpiration(expirationDate) // Sets the JWT Claims exp (expiration) value

.signWith(signingKey, SIGNATURE_ALGORITHM);

// Builds the JWT and serializes it to a compact, URL-safe string

return builder.compact();

}

/**

* Get User from the given token

*/

public static AccountDetail getUserFromToken(String token) {

//decode jwt token

final Claims claims = decodeJWT(token);

//lấy thông tin người dùng trong claims

AccountDetail user = new AccountDetail();

user.setUsername(claims.getSubject());

user.setFullName(claims.get("fullname").toString());

user.setAvatar(claims.get("avatar").toString());

user.setRoles((List<String>) claims.get("roles"));

return user;

}

/**

* Check if the token was issued by the server and if it's not expired

*/

public static Boolean isTokenExpired(String token) {

final Date expiration = getExpirationDateFromToken(token);

return expiration.before(new Date());

}

private static Date getExpirationDateFromToken(String token) {

return getClaimFromToken(token, Claims::getExpiration);

}

private static <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {

final Claims claims = decodeJWT(token);

return claimsResolver.apply(claims);

}

private static Claims decodeJWT(String jwt) {

// This line will throw an exception if it is not a signed JWS (as expected)

return Jwts.parser() // Configured and then used to parse JWT strings

.setSigningKey(DatatypeConverter.parseBase64Binary(SECRET_KEY)) // Sets the signing key used to verify

// any discovered JWS digital signature

.parseClaimsJws(jwt) // Parses the specified compact serialized JWS string based

.getBody();

}

}

  • Tạo lớp hanam88.filter\AuthFilter.java

@Provider

@Priority(Priorities.AUTHENTICATION) // xảy ra trước khi xác thực

public class AuthFilter implements ContainerRequestFilter {

private static final String REALM = "hanam88";

private static final String AUTHENTICATION_SCHEME = "Bearer";

/**

* Extracting the token from the request and validating it

*

* The client should send the token in the standard HTTP Authorization header of

* the request. For example: Authorization: Bearer <token-goes-here>

*

* Finally, set the security context of the current request

*/

@Override

public void filter(ContainerRequestContext requestContext) throws IOException {

// (1) Get Token Authorization from the header

String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

// (2) Validate the Authorization header

if (!isTokenBasedAuthentication(authorizationHeader)) {

return;

}

// (3) Extract the token from the Authorization header

String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();

try {

// (4) Validate the token

if (JwTokenHelper.isTokenExpired(token)) {

abortWithUnauthorized(requestContext);

return;

}

// (5) Getting the User information from token

AccountDetail user = JwTokenHelper.getUserFromToken(token);

// (6) Overriding the security context of the current request

SecurityContext oldContext = requestContext.getSecurityContext();

requestContext.setSecurityContext(new BasicSecurityContext(user, oldContext.isSecure()));

} catch (Exception e) {

abortWithUnauthorized(requestContext);

}

}

private boolean isTokenBasedAuthentication(String authorizationHeader) {

// Check if the Authorization header is valid

// It must not be null and must be prefixed with "Bearer" plus a whitespace

// The authentication scheme comparison must be case-insensitive

return authorizationHeader != null

&& authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");

}

private void abortWithUnauthorized(ContainerRequestContext requestContext) {

// Abort the filter chain with a 401 status code response

// The WWW-Authenticate header is sent along with the response

Response respone = Response.status(Response.Status.UNAUTHORIZED) // 401 Unauthorized

.header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME + " realm=\"" + REALM + "\"")

.entity("Bạn không thể truy cập vào tài nguyên này") // the response entity

.build();

requestContext.abortWith(respone);

}

}

  • Tạo lớp hanam88.filter\AuthService.java

@Path("/gettoken")

public class AuthService {

/**

* Xác thực người dùng với username/password của họ phát hành token

*

* @param username

* @param password

* @return JSON Web Token (JWT)

*/

@POST

@Produces(MediaType.TEXT_PLAIN)

@Consumes(MediaType.APPLICATION_JSON)

public Response createToken(String usermodel) {

var gson=new Gson();

var user=gson.fromJson(usermodel, AccountDetail.class);

String username=user.getUsername();

// hóa password MD5

String password=MD5Encoder.GenerateMD5(user.getPassword());

// Xác thực người dùng bằng thông tin đăng nhập được cung cấp

AccountDAO accountDAO = new AccountDAO();

//lấy tài khoản theo username

user = accountDAO.getUser(username);

if (user == null || !user.getPassword().equals(password)) {

return Response.status(Response.Status.FORBIDDEN)

.entity("Sai tên hoặc mật khẩu") // tạo thực thể trả về

.build();

}

// Tạo token dựa trên thông tin user

String token = JwTokenHelper.createJWT(user);

// trả về chuối token

return Response.ok(token).build();

}

}

  • Tạo lớp hanam88.filter\StudentService.java

@Path("/students")

@PermitAll

public class StudentService {

private StudentDAO dao=new StudentDAO();

@GET

@Produces(MediaType.APPLICATION_JSON)

public Response getAll() {

var gson=new GsonBuilder().setDateFormat("dd/MM/yyyy").create();

var students= gson.toJson(dao.getAll());

return Response.ok(students).build();

}

@GET

@Path("/{id}")

@Produces(MediaType.APPLICATION_JSON)

public Response get(@PathParam("id") String id) {

return Response.ok(dao.getById(id)).build();

}

@RolesAllowed("ROLE_ADMIN")

@POST

@Consumes(MediaType.APPLICATION_JSON)

@Produces(MediaType.APPLICATION_JSON)

public Response insert(String student, @Context SecurityContext securityContext) {

//Lấy thông tin người dùng trên server

var user=(AccountDetail) securityContext.getUserPrincipal();

System.out.println("Xin chào: " + user.getFullName());

System.out.println("Họ tên: " + user.getUsername());

System.out.println("Ảnh: " + user.getAvatar());

//xử convert json

var gson=new GsonBuilder().setDateFormat("dd/MM/yyyy").create();

var st=gson.fromJson(student, Student.class);

dao.insert(st);

return Response.ok("Thêm thành công").build();

}

@RolesAllowed({"ROLE_ADMIN", "ROLE_STUDENT" })

@PUT

@Path("/{id}")

public Response update(@PathParam("id") String id, String student) {

//xử convert json

var gson=new GsonBuilder().setDateFormat("dd/MM/yyyy").create();

var st=gson.fromJson(student, Student.class);

if(!st.getStudentId().equals(id))

return Response.ok("Mã không khớp!").build();

dao.update(st);

return Response.ok("Sửa thành công!").build();

}

@RolesAllowed( "ROLE_ADMIN")

@DELETE

@Path("/{id}")

public Response delete(@PathParam("id") String id) {

dao.delete(id);

return Response.ok("Xóa thành công!").build();

}

}

Bước 7: Run application

  • Kích chuột phải vào project chọn Run As -> Run on Server -> Tomcat v9.0
  • Mở phần mềm Postman để test

GET: /api/students (không yêu cầu login)

POST: /api/students/gettoken (đăng nhập lấy token)

POST: /api/students (thêm sinh viên yêu cầu token kèm theo)

Link download source code bài viết Security trong Restful Webservice sử dụng Jersey 2 để sinh ra JWT

Video 

 

thay lời cảm ơn!

QUẢNG CÁO - TIẾP THỊ