650 likes | 783 Views
CS441 CURRENT TOPICS IN PROGRAMMING LANGUAGES. Lecture 19. George Koutsogiannakis /Summer 2011. Topics. Java Persistence Query Language (JPQL) Security in Java EE. Security Roles. Web Security. JPQL. Allows writing of queries that are portable across data stores (databases).
E N D
CS441 CURRENT TOPICS IN PROGRAMMING LANGUAGES Lecture 19 George Koutsogiannakis/Summer 2011
Topics • Java Persistence Query Language (JPQL) • Security in Java EE. • Security Roles. • Web Security.
JPQL • Allows writing of queries that are portable across data stores (databases). • The Java Persistence Query Language (JPQL) is a platform-independent object-oriented query language defined as part of the Java Persistence API specification. • JPQL is used to make queries against entities stored in a relational database.
JPQL • It is heavily inspired by SQL, and its queries resemble SQL queries in syntax, but operate against JPA entity objects rather than directly with database tables. • In addition to retrieving objects (SELECT queries), JPQL supports bulk UPDATE and DELETE queries.
JPQL • JPQL looks like SQL but it has some differences and enhancements over SQL: • Like relational tables, entities are typically related to each other with relationships • such as one-to-one, one-to-many, many-to-one, or many-to-many. • Java applications dealing with entities require a standard mechanism to access and navigate entity instances. • The Java Persistence Query Language (JPQL) is specifically designed for this purpose.
JPQL • The main difference between JPQL and SQL lies in that the former deals with JPA entities, while the latter deals directly with relational data. • JPQL eliminates the need for you to use JDBC API from your Java code—the container does all this work for you behind the scenes. • JPQL lets you define queries using one of the following three statements: SELECT, UPDATE, or DELETE.
JPQL and JPA • The EntityManager API interface offers methods that can also be used to perform retrieve, update and delete operations over entities. • In particular, these are find, merge, and remove methods. • The use of those methods, however, is typically limited to a single entity instance (that is a single row of data).
JPQL and JPA • JPQL statements do not have such a limitation—you can define bulk update and delete operations over sets of entities (many rows), and define queries returning sets of entity instances. • To issue a JPQL query from within your Java code, you have to utilize appropriate methods of the EntityManager API and Query API, performing the following general steps:
JPQL and JPA • Obtain an instance of EntityManager, using injection or explicitly through an EntityManagerFactory instance. • Create an instance of Query by invoking an appropriate EntityManager's method, such as createQuery. • Set a query parameter or parameters, if any, using an appropriate Query's setParameter method.
JPQL and JPA • If needed, set the maximum number of instances to retrieve and/or specify the position of the first instance to retrieve, using the setMaxResults and/or setFirstResult Query's methods. • If needed, set a vendor-specific hint, using the setHint Query's method.
JPQL and JPA • If needed, set the flush mode for the query execution with the setFlushMode Query's method, overriding the entity manager's flush mode. • Execute the query using an appropriate Query's method: getSingleResult or getResultList. • In the case of an update or delete operation, though, you must use the executeUpdate method, which returns the number of entity instances updated or deleted.
JPQL and JPA • The following code fragment is taken from a servlet's doGet method that uses a JPQL query to obtain information about all the customers stored in the underlying relational table associated with the Customer entity specified in the query. @PersistenceUnit private EntityManagerFactory emf; public void doGet( EntityManager em = emf.createEntityManager(); PrintWriter out=response.getWriter(); List<Customer> arr_cust = (List<Customer>)em.createQuery( "SELECT c FROM Customer c") .getResultList(); out.println("List of all customers: "+“</br>");
JPQL and JPA Iterator i = arr_cust.iterator(); Customer cust; while (i.hasNext()) { cust = (Customer) i.next(); out.println(cust.getCust_id()+"<br/>"); out.println(cust.getCust_name()+"<br/>"); out.println(cust.getEmail()+"<br/>"); out.println(cust.getPhone()+"<br/>"); out.println("----------------" + "<br/>"); }
JPQL and JPA • Of special interest here are: • the createQuery method of the EntityManager instance and t • he getResultList method of the Query instance. • The EntityManager's createQuery is used to create the Query instance whose getResultList method is then used to execute the JPQL query passed to createQuery as the parameter. • The Query's getResultList method returns the result of a query as a List whose elements, in this particular example, are cast to type Customer.
JPQL and JPA • With setParameter, you can bind both named and positional parameters • Integer cust_id =2; Customer cust = (Customer)em.createQuery("SELECT c FROM Customer c WHERE c.cust_id=:cust_id") .setParameter("cust_id", cust_id) .getSingleResult(); out.println("Customer with id "+cust.getCust_id()+" is: "+ cust.getCust_name()+"<br/>");
JPQL and JPA • Similarly, to obtain the entire list of customers' names, you might use the following code: ... • List<String> arr_cust_name = (List<String>)em.createQuery("SELECT c.cust_name FROM Customer c") .getResultList(); out.println("List of all customers: "+"<br/>"); Iterator i = arr_cust_name.iterator(); String cust_name; while (i.hasNext()) { cust_name = (String) i.next(); out.println(cust_name+"<br/>"); }
JPQL and JPA • Like SQL, JPQL lets you define join queries. • JPQL is still evolving, and doesn't have many of important features available in SQL as yet.
JPQL-EXAMPLE • Suppose we have JPA entity classes defined like this (getter and setter methods omitted for simplicity): • @Entity public class Author { @Id private Integer id; private String firstName; private String lastName; @ManyToMany private List<Book> books; ……………………………………….. }
JPQL-EXAMPLE @Entity public class Book { @Id private Integer id; private String title; private String isbn; @ManyToOne private Publisher publisher; @ManyToMany private List<Author> authors; ……………………………………………………… }
JPQL-EXAMPLE @Entity public class Publisher { @Id private Integer id; private String name; private String address; @OneToMany(mappedBy = "publisher") private List<Book> books; ……………………………………. }
JPQL-EXAMPLE • In this example we have annotated the relationships: • An Author entity (one row of data from the Book table) relates to many entities of Book(many rows from Book table) and vice versa. • A Publisher entity can relate to many Book entities but a Book entity can only relate to one Publisher entity. • Notice that the many relationship is handled with List structures of the corresponding type (entity). • Thus we have an easy way to establish the relationships between tables programmatically.
SQL VERSION QUERIES • SQL queries can be written: • A simple SQL query to retrieve the list of all authors, ordered alphabetically, would be: • SELECT a FROM Author a ORDER BY a.firstName, a.lastName • To retrieve the list of authors that have ever been published by XYZ Press: • SELECT DISTINCT a FROM Author a INNER JOIN p.books b WHERE b.publisher.name = 'XYZ Press'
JPQL • Or, Instead of using SQL statements we could write a JPQL function , for example, returning a list of authors with the given first name as follows: • import javax.persistence.EntityManager; import javax.persistence.Query; import org.apache.commons.lang.StringUtils; ... @SuppressWarnings("unchecked") public List<Author> getAuthorsByLastName(String lastNameParam) { String queryString = "SELECT auth FROM Author auth,WHERE :lastName IS NULLORLOWER(auth.lastName) = :lastNameParam"; Query query = getEntityManager().createQuery(queryString); query.setParameter("lastName", StringUtils.lowerCase(lastNameParam)); return query.getResultList(); }
JPQL • In the previous example the JPQL syntax for the SELECT query statement was used: • JPQL language keywords are underlined. Clauses are keywords and can be lower case or upper case. • Entity names can be used as they appear in the class name for the Entity. • auth is an identification variable defined in the statement as of type Author • lastName is a field of the Entity. • lastNameParam is a parameter passed to the method. The SELECT statement selects the author last names that match the value of this parameter.
JPQL • The WHERE clause restricts the values to a conditional expression. Notice that a colon is used like =: or >: or <:
JPQL • Thus, JPQL has its own syntax somewhat different than SQL. • Details of JPQL syntax can be found on the web. One possible site is: http://edocs.bea.com/kodo/docs41/full/html/ejb3_langref.htm#ejb3_langref_stmntypes
Security • A container provides two kinds of security: • Declarative • Expresses an application component’s security requirements using deployment descriptors. • Annotations in the code are translated and entered into the deployment descriptor file by the IDE (or the deployment descriptor can be edited manually). • Programmatic security. • Embedded in an application to make security decisions.
Security • Assume communications between a Client and a EE application that contains web and ejb parts. • There are two levels of security • Security handled by the web container • Security handled by the ejb container.
Security • Initial Security handled by the web container • In this approach: • Client sends a request. • Web Server sends back a form asking for user id and password. • Client submits the information. • Server validates the information. • Server allows client requests based on the acceptable security role of the client. • Client submits data to be processed by the Session Bean.
Security • The request now is ready to be submitted to the ejb part of the application. • Second level of security now has to be established with the ejb container. • The EJB container is responsible for enforcing access control on the enterprise bean method. • It consults the security policy (derived from the deployment descriptor) associated with the enterprise bean to determine the security roles that are permitting access to the method. • For each role, the EJB container uses the security context associated with the call to determine if it can map the caller to the role.
Security • The ejb container will evaluate the credentials submitted by the web container and issue either a call: • Is authorized or • Not authorized • if the call is authorized, the container dispatches control to the enterprise bean method. • The result of the bean’s execution of the call is returned to the JSP (or servlet), and ultimately to the user by the web server and the web client.
Security Functions • A properly implemented security mechanism will provide the following functionality: • Prevent unauthorized access to application functions and business or personal data. • Hold system users accountable for operations they perform (non-repudiation). • Protect a system from service interruptions and other breaches that affect quality of service.
Security APIs • Security APIs supported are • SE APIs • Java Authentication and Authorization Service (JAAS) • Java Generic Security Services (Java GSS-API): Java GSS-API is a token-based API used to securely exchange messages between communicating applications. The GSS-API offers application programmers uniform access to security services atop a variety of underlying security mechanisms, including Kerberos.
Security APIs • Java Secure Sockets Extension (JSSE). • Simple Authentication and Security Layer (SASL): SASL is an Internet standard (RFC 2222) that specifies a protocol for authentication and optional establishment of a security layer between client and server applications. • EE • Can be implemented using declarative or programmatic techniques.
Security Layers • Application-Layer Security. • In Java EE, component containers are responsible for providing application-layer security. • Provides security services for a specific application type tailored to the needs of the application. • Security is uniquely suited to the needs of the application. • Security is fine-grained, with application-specific settings. • The application is dependent on security attributes that are not transferable between application types.
Security Layers • Transport-Layer Security. • Relies on secure HTTP transport (HTTPS) using Secure Sockets Layer (SSL). • Point-to-Point security mechanism that can be used for authentication, message integrity, and confidentiality. • The client and server agree on an appropriate algorithm. • A key is exchanged using public-key encryption and certificate-based authentication. • A symmetric cipher is used during the information exchange.
Security Layers • Message-Layer Security (Web Services) • Security information is contained within the SOAP message and/or SOAP message attachment. For example, a portion of the message may be signed by a sender and encrypted for a particular receiver (this is for Web Services). • When the message is sent from the initial sender, it may pass through intermediate nodes before reaching its intended receiver. • The encrypted portions continue to be opaque to any intermediate nodes and can only be decrypted by the intended receiver. For this reason, message-layer security is also sometimes referred to as end-to-end security.
Security Layers • Security stays with the message over all hops and after the message arrives at its destination. • Security can be selectively applied to different portions of a message. • Message security can be used with intermediaries over multiple hops. • Message security is independent of the application environment or transport protocol.
Security for Web Applications • A web application is created by developer. • It is passed to a deployer who is responsible for the deployment of the application on servers. • The deployer (person who is responsible for deploying the application on the server(s)) must set the security for the application : • Either by adding annotations . • Or, by modifying the deployment descriptor (web.xml)
Security for Web Applications • Deployment Descriptor • Setting the attribute full of element web-app determines if the container will supplement the security setting in web.xml with the reading of annotations • full=true means that the container will ignore annotations in the servlet classes. • full=false means that the container will consider the annotations. • Default is full=false. • Because there are not annotations, as yet, for all security settings a combination of annotations and explicit deployment descriptor settings may be needed.
Security for Web Applications • Annotations for web application components are described in the Java Servlet 2.5 Specification which amongst other changes: • Introduced all kinds of annotations to the servlet API (not just security annotations). • Make sure that the web server supports servlet API 2.5 and up (most recent versions of Tomcat do support it (6.0 and up)).
Web-ApplicationsUsing Annotations Examples • @DeclareRoles • This annotation is used to define the security roles that comprise the security model of the application. • This annotation is specified on a class. • Role is defined bycalling isUserInRole method from within the methods of the annotated class i.e. @DeclareRoles("BusinessAdmin") public class CalculatorServlet { //... } • Where BusinessAdmin is the security role specified, • The value of this parameter can include a list of security roles specified by the application.
Web-ApplicationsUsing Annotations Examples • This is the same as if we had declared the security role in the web.xml of the applications as: <web-app> <security-role> <role-name>BusinessAdmin</role-name> </security-role> </web-app>
Web-ApplicationsUsing Annotations Examples • Multiple security roles for the application can be annotated as: @DeclareRoles({"Administrator", "Manager", "Employee"}) • When a call is made to isUserInRole from the annotated class, the caller identity associated with the invocation of the class is tested for membership in the role with the same name as the argument to isUserInRole. • If a security-role-ref has been defined for the argument role-name, the caller is tested for membership in the role mapped to the role-name.
Web-ApplicationsUsing Annotations Examples • Another example of a security annotation is: • @RunAs AnnotationName • RunAs defines the role of the application during execution in a Java EE container and AnnotationName is some name used to define the role. • It can be specified on a class, allowing developers to execute an application under a particular role. The role must map to the user/group information in the container’s security realm. • The value element in the annotation is the name of a security role of the application during execution in a Java EE container.
Web-ApplicationsUsing Annotations Examples • The @RunAs annotation is equivalent to the run-as element in the deployment descriptor. @RunAs("Admin") public class CalculatorServlet { @EJB private ShoppingCart myCart; public void doGet(HttpServletRequest, req, HttpServletResponse res) { //.... myCart.getTotal(); //.... } } //....
Security Roles • What are the security roles: • A role is an abstract name for the permission to access certain resources. • The roles are defined in the data source based on the abstract names used.
Example Security Elements in Deployment Descriptor • <servelt> <security-role-ref> <role-name>Mgm</role-name> // The security role name used is the value of the security name used in the code of the servlet i.e HttpServletRequest.isUserInRole(String Mgm);