| type=page |
| status=published |
| title=Securing Applications |
| next=webservices.html |
| prev=part-apps-and-app-comps.html |
| ~~~~~~ |
| |
| = Securing Applications |
| |
| [[GSDVG00006]][[beabg]] |
| |
| |
| [[securing-applications]] |
| == 4 Securing Applications |
| |
| This chapter describes how to write secure Jakarta EE applications, which |
| contain components that perform user authentication and access |
| authorization for the business logic of Jakarta EE components. |
| |
| For information about administrative security for the {productName}, see the link:security-guide.html#GSSCG[{productName} |
| Security Guide]. |
| |
| For general information about Jakarta EE security, see |
| https://eclipse-ee4j.github.io/jakartaee-tutorial/#security-2[Security] |
| in The Jakarta EE Tutorial. |
| |
| The following topics are addressed here: |
| |
| * link:#beabh[Security Goals] |
| * link:#beabi[{productName} Specific Security Features] |
| * link:#beabj[Container Security] |
| * link:#beacr[Roles, Principals, and Principal to Role Mapping] |
| * link:#beabo[Realm Configuration] |
| * link:#BACDEIHB[Jakarta EE Security API Support] |
| * link:#beabt[JACC Support] |
| * link:#beabu[Pluggable Audit Module Support] |
| * link:#beabx[The `server.policy` File] |
| * link:#beaca[Configuring Message Security for Web Services] |
| * link:#beacm[Programmatic Login Using the ProgrammaticLogin Class] |
| * link:#beacq[User Authentication for Single Sign-on] |
| * link:#gizel[Adding Authentication Mechanisms to the Servlet Container] |
| |
| |
| [NOTE] |
| ==== |
| The Web Profile of the {productName} supports the EJB 3.1 Lite |
| specification, which allows enterprise beans within web applications, |
| among other features. The full {productName} supports the entire EJB |
| 3.1 specification. For details, see |
| http://jcp.org/en/jsr/detail?id=318[JSR 318] |
| (`http://jcp.org/en/jsr/detail?id=318`). |
| ==== |
| |
| |
| [[beabh]][[GSDVG00114]][[security-goals]] |
| |
| === Security Goals |
| |
| In an enterprise computing environment, there are many security risks. |
| The goal of the {productName} is to provide highly secure, |
| interoperable, and distributed component computing based on the Jakarta EE |
| security model. Security goals include: |
| |
| * Full compliance with the Jakarta EE security model. This includes EJB and |
| servlet role-based authorization. |
| * Support for single sign-on across all {productName} applications |
| within a single security domain. |
| * Support for web services message security. |
| * Security support for application clients. |
| * Support for several underlying authentication realms, such as simple |
| file and Lightweight Directory Access Protocol (LDAP). Certificate |
| authentication is also supported for Secure Socket Layer (SSL) client |
| authentication. For Solaris, OS platform authentication is supported in |
| addition to these. |
| * Support for declarative security through {productName} specific |
| XML-based role mapping. |
| * Support for Java Authorization Contract for Containers (JACC) |
| pluggable authorization as included in the Jakarta EE specification and |
| defined by http://www.jcp.org/en/jsr/detail?id=115[Java Specification |
| Request (JSR) 115] (`http://www.jcp.org/en/jsr/detail?id=115`). |
| * Support for Java Authentication Service Provider Interface for |
| Containers as included in the Jakarta EE specification and defined by |
| http://www.jcp.org/en/jsr/detail?id=196[JSR 196] |
| (`http://www.jcp.org/en/jsr/detail?id=196`). |
| * Support for Web Services Interoperability Technologies (WSIT) as described in |
| https://eclipse-ee4j.github.io/jakartaee-tutorial/#web-services-interoperability-and-jakarta-xml-web-services[ |
| Jakarta EE Tutorial]. |
| * Support for the Jakarta EE Security API as included in the Jakarta EE |
| specification and defined by https://jcp.org/en/jsr/detail?id=375[JSR |
| 375] (`https://jcp.org/en/jsr/detail?id=375`) |
| |
| [[beabi]][[GSDVG00115]][[glassfish-server-specific-security-features]] |
| |
| === {productName} Specific Security Features |
| |
| The {productName} supports the Jakarta EE security model, as well as the |
| following features which are specific to the {productName}: |
| |
| * Message security; see link:#beaca[Configuring Message Security for Web |
| Services] |
| * Single sign-on across all {productName} applications within a |
| single security domain; see link:#beacq[User Authentication for Single |
| Sign-on] |
| * Programmatic login; see link:#beacm[Programmatic Login Using the |
| ProgrammaticLogin Class] |
| |
| [[beabj]][[GSDVG00116]][[container-security]] |
| |
| === Container Security |
| |
| The component containers are responsible for providing Jakarta EE |
| application security. The container provides two security forms: |
| |
| * link:#beabl[Declarative Security] |
| * link:#beabk[Programmatic Security] |
| |
| Annotations (also called metadata) enable a declarative style of |
| programming, and so encompass both the declarative and programmatic |
| security concepts. Users can specify information about security within a |
| class file using annotations. When the application is deployed, this |
| information can either be used by or overridden by the application or |
| module deployment descriptor. |
| |
| [[beabl]][[GSDVG00362]][[declarative-security]] |
| |
| ==== Declarative Security |
| |
| Declarative security means that the security mechanism for an |
| application is declared and handled externally to the application. |
| Deployment descriptors describe the Jakarta EE application's security |
| structure, including security roles, access control, and authentication |
| requirements. |
| |
| The {productName} supports the deployment descriptors specified by |
| Jakarta EE and has additional security elements included in its own |
| deployment descriptors. Declarative security is the application |
| deployer's responsibility. For more information about {productName} |
| deployment descriptors, see the link:application-deployment-guide.html#GSDPG[{productName} Application Deployment Guide]. |
| |
| There are two levels of declarative security, as follows: |
| |
| * link:#beabm[Application Level Security] |
| * link:#beabn[Component Level Security] |
| |
| [[beabm]][[GSDVG00239]][[application-level-security]] |
| |
| ===== Application Level Security |
| |
| For an application, roles used by any application must be defined in |
| `@DeclareRoles` annotations in the code or `role-name` elements in the |
| application deployment descriptor (`application.xml`). Those role names |
| are scoped to the EJB XML deployment descriptors (`ejb-jar.xml` and |
| `glassfish-ejb-jar.xml` files) and to the servlet XML deployment |
| descriptors (`web.xml` and `glassfish-web.xml` files). For an |
| individually deployed web or EJB module, you define roles using |
| `@DeclareRoles` annotations or `role-name` elements in the Jakarta EE |
| deployment descriptor files `web.xml` or `ejb-jar.xml`. |
| |
| To map roles to principals and groups, define matching |
| `security-role-mapping` elements in the `glassfish-application.xml`, |
| `glassfish-ejb-jar.xml`, or `glassfish-web.xml` file for each |
| `role-name` used by the application. By default, group principal names |
| are mapped to roles of the same name. Accordingly, the Default Principal |
| To Role Mapping setting is enabled by default on the Security page of |
| the {productName} Administration Console. This default role mapping |
| definition is in effect if you do not define your own mapping in the |
| deployment descriptor for your application as described in this section. |
| For more information, see link:#beacr[Roles, Principals, and Principal |
| to Role Mapping]. |
| |
| [[beabn]][[GSDVG00240]][[component-level-security]] |
| |
| ===== Component Level Security |
| |
| Component level security encompasses web components and EJB components. |
| |
| A secure web container authenticates users and authorizes access to a |
| servlet or JSP by using the security policy laid out in the servlet XML |
| deployment descriptors (`web.xml` and `glassfish-web.xml` files). |
| |
| The EJB container is responsible for authorizing access to a bean method |
| by using the security policy laid out in the EJB XML deployment |
| descriptors (`ejb-jar.xml` and `glassfish-ejb-jar.xml` files). |
| |
| [[beabk]][[GSDVG00363]][[programmatic-security]] |
| |
| ==== Programmatic Security |
| |
| Programmatic security involves an EJB component or servlet using method |
| calls to the security API, as specified by the Jakarta EE security model, |
| to make business logic decisions based on the caller or remote user's |
| security role. Programmatic security should only be used when |
| declarative security alone is insufficient to meet the application's |
| security model. |
| |
| The API for programmatic security consists of methods of the Jakarta EE |
| Security API `SecurityContext` interface, and methods of the EJB |
| `EJBContext` interface and the servlet `HttpServletRequest` interface. |
| The {productName} supports these interfaces as specified in the Java |
| EE specification. |
| |
| There is also a proprietary Glassfish API for programmatic login. See |
| link:#beacm[Programmatic Login Using the ProgrammaticLogin Class]. |
| |
| For more information about programmatic security, see |
| https://eclipse-ee4j.github.io/jakartaee-tutorial/#using-programmatic-security-with-web-applications[ |
| Using Programmatic Security] in the The Jakarta EE Tutorial. |
| |
| [[beacr]][[GSDVG00117]][[roles-principals-and-principal-to-role-mapping]] |
| |
| === Roles, Principals, and Principal to Role Mapping |
| |
| By default, any groups that an authenticated user belongs to will be |
| mapped to roles with the same names. Therefore, the Default Principal To |
| Role Mapping setting is enabled by default on the Security page of the |
| GlassFish Administration Console. To change the default mapping you can |
| clear this setting. For applications, you define roles in |
| `@DeclareRoles` annotations or the Jakarta EE deployment descriptor file |
| `application.xml`. You define the corresponding role mappings in the |
| {productName} deployment descriptor file `glassfish-application.xml`. |
| For individually deployed web or EJB modules, you define roles in |
| `@DeclareRoles` annotations or the Jakarta EE deployment descriptor files |
| `web.xml` or `ejb-jar.xml`. You define the corresponding role mappings |
| in the {productName} deployment descriptor files `glassfish-web.xml` |
| or `glassfish-ejb-jar.xml`. |
| |
| For more information regarding Jakarta EE deployment descriptors, see the |
| Jakarta EE Specification. For more information regarding {productName} |
| deployment descriptors, see "link:application-deployment-guide/dd-elements.html#GSDPG00007[Elements of the {productName} Deployment Descriptors]" in {productName} |
| Application Deployment Guide. |
| |
| Each `security-role-mapping` element in the `glassfish-application.xml`, |
| `glassfish-web.xml`, or `glassfish-ejb-jar.xml` file maps a role name |
| permitted by the application or module to principals and groups. For |
| example, a `glassfish-web.xml` file for an individually deployed web |
| module might contain the following: |
| |
| [source,xml] |
| ---- |
| <glassfish-web-app> |
| <security-role-mapping> |
| <role-name>manager</role-name> |
| <principal-name>jgarcia</principal-name> |
| <principal-name>mwebster</principal-name> |
| <group-name>team-leads</group-name> |
| </security-role-mapping> |
| <security-role-mapping> |
| <role-name>administrator</role-name> |
| <principal-name>dsmith</principal-name> |
| </security-role-mapping> |
| </glassfish-web-app> |
| ---- |
| |
| A role can be mapped to either specific principals or to groups (or |
| both). The principal or group names used must be valid principals or |
| groups in the realm for the application or module. Note that the |
| `role-name` in this example must match the `@DeclareRoles` annotations |
| or the `role-name` in the `security-role` element of the corresponding |
| `web.xml` file. |
| |
| You can also specify a custom principal implementation class. This |
| provides more flexibility in how principals can be assigned to roles. A |
| user's JAAS login module now can authenticate its custom principal, and |
| the authenticated custom principal can further participate in the |
| {productName} authorization process. For example: |
| |
| [source,xml] |
| ---- |
| <security-role-mapping> |
| <role-name>administrator</role-name> |
| <principal-name class-name="CustomPrincipalImplClass"> |
| dsmith |
| </principal-name> |
| </security-role-mapping> |
| ---- |
| |
| You can specify a default principal and a default principal to role |
| mapping, each of which applies to the entire {productName} instance. |
| The default principal to role mapping maps group principals to the same |
| named roles. Web modules that omit the `run-as` element in `web.xml` use |
| the default principal. Applications and modules that omit the |
| `security-role-mapping` element use the default principal to role |
| mapping. These defaults are part of the Security Service, which you can |
| access in the following ways: |
| |
| * In the Administration Console, select the Security component under the |
| relevant configuration. For details, click the Help button in the |
| Administration Console. |
| * Use the `asadmin set` command. For details, see the |
| link:reference-manual.html#GSRFM[{productName} Reference Manual]. For |
| example, you can set the default principal as follows. |
| + |
| [source] |
| ---- |
| asadmin set server-config.security-service.default-principal=dsmith |
| asadmin set server-config.security-service.default-principal-password=secret |
| ---- |
| You can set the default principal to role mapping as follows. |
| + |
| [source] |
| ---- |
| asadmin set server-config.security-service.activate-default-principal-to-role-mapping=true |
| asadmin set server-config.security-service.mapped-principal-class=CustomPrincipalImplClass |
| ---- |
| Default principal to role mapping is enabled by default. To disable it, |
| set the default principal to role mapping property to false. |
| |
| [[beabo]][[GSDVG00118]][[realm-configuration]] |
| |
| === Realm Configuration |
| |
| The following topics are addressed here: |
| |
| * link:#beabp[Supported Realms] |
| * link:#beabq[How to Configure a Realm] |
| * link:#beabr[How to Set a Realm for an Application or Module] |
| * link:#beabs[Creating a Custom Realm] |
| |
| [[beabp]][[GSDVG00364]][[supported-realms]] |
| |
| ==== Supported Realms |
| |
| The following realms are supported in the current release of the |
| {productName}: |
| |
| * `file` - Stores user information in a file. This is the default realm |
| when you first install the {productName}. |
| * `ldap` - Stores user information in an LDAP directory. |
| * `jdbc` - Stores user information in a database. |
| + |
| In the JDBC realm, the server gets user credentials from a database. The |
| {productName} uses the database information and the enabled JDBC |
| realm option in the configuration file. For digest authentication, a |
| JDBC realm should be created with `jdbcDigestRealm` as the JAAS context. |
| * `certificate` - Sets up the user identity in the {productName} |
| security context, and populates it with user data obtained from |
| cryptographically verified client certificates. |
| * `solaris` - Allows authentication using Solaris `username+password` |
| data. This realm is only supported on the Solaris operating system, |
| version 9 and above. |
| |
| For information about configuring realms, see link:#beabq[How to |
| Configure a Realm]. |
| |
| [[beabq]][[GSDVG00365]][[how-to-configure-a-realm]] |
| |
| ==== How to Configure a Realm |
| |
| You can configure a realm in one of these ways: |
| |
| * In the Administration Console, open the Security component under the |
| relevant configuration and go to the Realms page. For details, click the |
| Help button in the Administration Console. |
| * Use the `asadmin create-auth-realm` command to configure realms on |
| local servers. For details, see the link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| [[beabr]][[GSDVG00366]][[how-to-set-a-realm-for-an-application-or-module]] |
| |
| ==== How to Set a Realm for an Application or Module |
| |
| The following deployment descriptor elements have optional `realm` or |
| `realm-name` data subelements or attributes that override the domain's |
| default realm: |
| |
| * `glassfish-application` element in `glassfish-application.xml` |
| * `web-app` element in `web.xml` |
| * `as-context` element in `glassfish-ejb-jar.xml` |
| * `client-container` element in `sun-acc.xml` |
| * `client-credential` element in `sun-acc.xml` |
| |
| If modules within an application specify realms, these are ignored. If |
| present, the realm defined in `glassfish-application.xml` is used, |
| otherwise the domain's default realm is used. |
| |
| For example, a realm is specified in `glassfish-application.xml` as |
| follows: |
| |
| [source,xml] |
| ---- |
| <glassfish-application> |
| ... |
| <realm>ldap</realm> |
| </glassfish-application> |
| ---- |
| |
| For more information about the deployment descriptor files and elements, |
| see "link:application-deployment-guide/dd-elements.html#GSDPG00007[Elements of the {productName} Deployment |
| Descriptors]" in {productName} Application |
| Deployment Guide. |
| |
| [[beabs]][[GSDVG00367]][[creating-a-custom-realm]] |
| |
| ==== Creating a Custom Realm |
| |
| You can create a custom realm by providing a custom Java Authentication |
| and Authorization Service (JAAS) login module class and a custom realm |
| class. Note that client-side JAAS login modules are not suitable for use |
| with the {productName}. |
| |
| To activate the custom login modules and realms, place the JAR files in |
| the domain-dir``/lib`` directory or the class files in the |
| domain-dir`/lib/classes` directory. For more information about class |
| loading in the {productName}, see link:class-loaders.html#beade[Class |
| Loaders]. |
| |
| JAAS is a set of APIs that enable services to authenticate and enforce |
| access controls upon users. JAAS provides a pluggable and extensible |
| framework for programmatic user authentication and authorization. JAAS |
| is a core API and an underlying technology for Jakarta EE security |
| mechanisms. For more information about JAAS, refer to the JAAS |
| specification for Java SDK, available at |
| `http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136007.html`. |
| |
| For general information about realms and login modules, see the section |
| about working with realms, users, groups, and roles in |
| https://eclipse-ee4j.github.io/jakartaee-tutorial/#security-2[ |
| Introduction to Security in the Jakarta EE Platform] |
| in The Jakarta EE Tutorial. |
| |
| For Javadoc tool pages relevant to custom realms, see the |
| `com.sun.appserv.security` package. |
| |
| Custom login modules must extend the |
| `com.sun.appserv.security.AppservPasswordLoginModule` class. This class |
| implements javax.security.auth.spi.LoginModule. Custom login modules |
| must not implement LoginModule directly. |
| |
| Custom login modules must provide an implementation for one abstract |
| method defined in `AppservPasswordLoginModule`: |
| |
| [source,java] |
| ---- |
| abstract protected void authenticateUser() throws LoginException |
| ---- |
| |
| This method performs the actual authentication. The custom login module |
| must not implement any of the other methods, such as `login`, `logout`, |
| `abort`, `commit`, or `initialize`. Default implementations are provided |
| in `AppservPasswordLoginModule` which hook into the {productName} |
| infrastructure. |
| |
| The custom login module can access the following protected object |
| fields, which it inherits from `AppservPasswordLoginModule`. These |
| contain the user name and password of the user to be authenticated: |
| |
| [source,java] |
| ---- |
| protected String _username; |
| protected String _password; |
| ---- |
| |
| The `authenticateUser` method must end with the following sequence: |
| |
| [source,java] |
| ---- |
| String[] grpList; |
| // populate grpList with the set of groups to which |
| // _username belongs in this realm, if any |
| commitUserAuthentication(grpList); |
| ---- |
| |
| Custom realms must extend the `com.sun.appserv.security.AppservRealm` |
| class and implement the following methods: |
| |
| [source,java] |
| ---- |
| public void init(Properties props) throws BadRealmException, NoSuchRealmException |
| ---- |
| |
| This method is invoked during server startup when the realm is initially |
| loaded. The `props` argument contains the properties defined for this |
| realm. The realm can do any initialization it needs in this method. If |
| the method returns without throwing an exception, the {productName} |
| assumes that the realm is ready to service authentication requests. If |
| an exception is thrown, the realm is disabled. |
| |
| [source,java] |
| ---- |
| public String getAuthType() |
| ---- |
| |
| This method returns a descriptive string representing the type of |
| authentication done by this realm. |
| |
| [source,java] |
| ---- |
| public abstract Enumeration getGroupNames(String username) throws |
| InvalidOperationException, NoSuchUserException |
| ---- |
| |
| This method returns an `Enumeration` (of `String` objects) enumerating |
| the groups (if any) to which the given `username` belongs in this realm. |
| |
| Custom realms that manage users must implement the following additional |
| methods: |
| |
| [source,java] |
| ---- |
| public abstract boolean supportsUserManagement(); |
| ---- |
| |
| This method returns `true` if the realm supports user management. |
| |
| [source,java] |
| ---- |
| public abstract Enumeration getGroupNames() throws BadRealmException; |
| ---- |
| |
| This method returns an `Enumeration` of all group names. |
| |
| [source,java] |
| ---- |
| public abstract Enumeration getUserNames() throws BadRealmException; |
| ---- |
| |
| This method returns an `Enumeration` of all user names. |
| |
| [source,java] |
| ---- |
| public abstract void refresh() throws BadRealmException; |
| ---- |
| |
| This method refreshes the realm data so that new users and groups are |
| visible. |
| |
| [source,java] |
| ---- |
| public abstract void persist() throws BadRealmException; |
| ---- |
| |
| This method persists the realm data to permanent storage. |
| |
| [source,java] |
| ---- |
| public abstract User getUser(String name) throws NoSuchUserException, |
| BadRealmException; |
| ---- |
| |
| This method returns the information recorded about a particular named |
| user. |
| |
| [source,java] |
| ---- |
| public abstract void addUser(String name, String password, String[] groupList) throws |
| BadRealmException, IASSecurityException; |
| ---- |
| |
| This method adds a new user, who cannot already exist. |
| |
| [source,java] |
| ---- |
| public abstract void removeUser(String name) throws NoSuchUserException, |
| BadRealmException; |
| ---- |
| |
| This method removes a user, who must exist. |
| |
| [source,java] |
| ---- |
| public abstract void updateUser(String name, String newName, String password, |
| String[] groups) throws NoSuchUserException, BadRealmException, IASSecurityException; |
| ---- |
| |
| This method updates data for a user, who must exist. |
| |
| |
| [NOTE] |
| ==== |
| The array passed to the `commitUseAuthentication` method should be newly |
| created and otherwise unreferenced. This is because the group name array |
| elements are set to null after authentication as part of cleanup. So the |
| second time your custom realm executes it returns an array with null |
| elements. |
| |
| Ideally, your custom realm should not return member variables from the |
| `authenticate` method. It should return local variables as the default |
| `JDBCRealm` does. Your custom realm can create a local `String` array in |
| its `authenticate` method, copy the values from the member variables, |
| and return the `String` array. Or it can use `clone` on the member |
| variables. |
| ==== |
| |
| |
| [[BACDEIHB]][[GSDVG563]][[java-ee-security-api-support]] |
| |
| === Jakarta EE Security API Support |
| |
| JSR-375 defines several authentication-related plugin SPIs, such as, |
| `HttpAuthenticationMechanism` interface, the `IdentityStore` and |
| `IdentityStoreHandler` interfaces: |
| |
| * `HttpAuthenticationMechanism`: An interface for modules that |
| authenticate callers to a web application. An application can supply its |
| own `HttpAuthenticationMechanism`, or use one of the default |
| implementations provided by the container. |
| * `IdentityStore`: This interface defines methods for validating a |
| caller's credentials (such as user name and password) and returning |
| group membership information. An application can provide its own |
| IdentityStore, or use the built in LDAP or Database store. |
| * `RememberMeIdentityStore`: This interface is a variation on the |
| `IdentityStore` interface, intended to address cases where an |
| authenticated user's identity should be remembered for an extended |
| period of time, so that the caller can return to the application |
| periodically without needing to present primary authentication |
| credentials each time. |
| |
| In addition to these authentication plugin SPIs, the Jakarta EE Security |
| API specification defines the `SecurityContext` API for use by |
| application code to query and interact with the current security |
| context. The `SecurityContext` interface defines methods that allow an |
| application to access security information about a caller, authenticate |
| a caller, and authorize a caller. These methods include |
| `getCallerPrincipal()`, `getPrincipalsByType()`, `isCallerInRole()`, |
| `authenticate()`, and `hasAccessToWebResource()`. |
| |
| [[beabt]][[GSDVG00119]][[jacc-support]] |
| |
| === JACC Support |
| |
| JACC (Java Authorization Contract for Containers) is part of the Jakarta EE |
| specification and defined by http://www.jcp.org/en/jsr/detail?id=115[JSR |
| 115] (`http://www.jcp.org/en/jsr/detail?id=115`). JACC defines an |
| interface for pluggable authorization providers. Specifically, JACC is |
| used to plug in the Java policy provider used by the container to |
| perform Jakarta EE caller access decisions. The Java policy provider |
| performs Java policy decisions during application execution. This |
| provides third parties with a mechanism to develop and plug in modules |
| that are responsible for answering authorization decisions during Java |
| EE application execution. The interfaces and rules used for developing |
| JACC providers are defined in the JACC 1.0 specification. |
| |
| The {productName} provides a simple file-based JACC-compliant |
| authorization engine as a default JACC provider, named `default`. An |
| alternate provider named `simple` is also provided. To configure an |
| alternate provider using the Administration Console, open the Security |
| component under the relevant configuration, and select the JACC |
| Providers component. For details, click the Help button in the |
| Administration Console. |
| |
| [[beabu]][[GSDVG00120]][[pluggable-audit-module-support]] |
| |
| === Pluggable Audit Module Support |
| |
| Audit modules collect and store information on incoming requests |
| (servlets, EJB components) and outgoing responses. You can create a |
| custom audit module. |
| |
| The following topics are addressed here: |
| |
| * link:#beabv[Configuring an Audit Module] |
| * link:#beabw[The `AuditModule` Class] |
| |
| [[beabv]][[GSDVG00368]][[configuring-an-audit-module]] |
| |
| ==== Configuring an Audit Module |
| |
| To configure an audit module, you can perform one of the following |
| tasks: |
| |
| * To specify an audit module using the Administration Console, open the |
| Security component under the relevant configuration, and select the |
| Audit Modules component. For details, click the Help button in the |
| Administration Console. |
| * You can use the `asadmin create-audit-module` command to configure an |
| audit module. For details, see the link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| [[beabw]][[GSDVG00369]][[the-auditmodule-class]] |
| |
| ==== The `AuditModule` Class |
| |
| You can create a custom audit module by implementing a class that |
| extends `com.sun.enterprise.security.audit.AuditModule`. |
| |
| For Javadoc tool pages relevant to audit modules, see the |
| `com.sun.enterprise.security.audit` package. |
| |
| The `AuditModule` class provides default "no-op" implementations for |
| each of the following methods, which your custom class can override. |
| |
| [source,java] |
| ---- |
| public void init(Properties props) |
| ---- |
| |
| The preceding method is invoked during server startup when the audit |
| module is initially loaded. The `props` argument contains the properties |
| defined for this module. The module can do any initialization it needs |
| in this method. If the method returns without throwing an exception, the |
| {productName} assumes the module realm is ready to service audit |
| requests. If an exception is thrown, the module is disabled. |
| |
| [source,java] |
| ---- |
| public void authentication(String user, String realm, boolean success) |
| ---- |
| |
| This method is invoked when an authentication request has been processed |
| by a realm for the given user. The `success` flag indicates whether the |
| authorization was granted or denied. |
| |
| [source,java] |
| ---- |
| public void webInvocation(String user, HttpServletRequest req, String type, boolean success) |
| ---- |
| |
| This method is invoked when a web container call has been processed by |
| authorization. The `success` flag indicates whether the authorization |
| was granted or denied. The `req` object is the standard |
| `HttpServletRequest` object for this request. The `type` string is one |
| of `hasUserDataPermission` or `hasResourcePermission` (see |
| http://www.jcp.org/en/jsr/detail?id=115[JSR 115] |
| (`http://www.jcp.org/en/jsr/detail?id=115`)). |
| |
| [source,java] |
| ---- |
| public void ejbInvocation(String user, String ejb, String method, boolean success) |
| ---- |
| |
| This method is invoked when an EJB container call has been processed by |
| authorization. The `success` flag indicates whether the authorization |
| was granted or denied. The `ejb` and `method` strings describe the EJB |
| component and its method that is being invoked. |
| |
| [source,java] |
| ---- |
| public void webServiceInvocation(String uri, String endpoint, boolean success) |
| ---- |
| |
| This method is invoked during validation of a web service request in |
| which the endpoint is a servlet. The `uri` is the URL representation of |
| the web service endpoint. The `endpoint` is the name of the endpoint |
| representation. The `success` flag indicates whether the authorization |
| was granted or denied. |
| |
| [source,java] |
| ---- |
| public void ejbAsWebServiceInvocation(String endpoint, boolean success) |
| ---- |
| |
| This method is invoked during validation of a web service request in |
| which the endpoint is a stateless session bean. The `endpoint` is the |
| name of the endpoint representation. The `success` flag indicates |
| whether the authorization was granted or denied. |
| |
| [[beabx]][[GSDVG00121]][[the-server.policy-file]] |
| |
| === The `server.policy` File |
| |
| Each {productName} domain has its own global J2SE policy file, |
| located in domain-dir``/config``. The file is named `server.policy`. |
| |
| The {productName} is a Jakarta EE compliant application server. As such, |
| it follows the requirements of the Jakarta EE specification, including the |
| presence of the security manager (the Java component that enforces the |
| policy) and a limited permission set for Jakarta EE application code. |
| |
| The following topics are addressed here: |
| |
| * link:#beaby[Default Permissions] |
| * link:#gilzz[System Properties] |
| * link:#beabz[Changing Permissions for an Application] |
| * link:#gbyah[Enabling and Disabling the Security Manager] |
| |
| [[beaby]][[GSDVG00370]][[default-permissions]] |
| |
| ==== Default Permissions |
| |
| Internal server code is granted all permissions. These are covered by |
| the `AllPermission` grant blocks to various parts of the server |
| infrastructure code. Do not modify these entries. |
| |
| Application permissions are granted in the default grant block. These |
| permissions apply to all code not part of the internal server code |
| listed previously. The {productName} does not distinguish between EJB |
| and web module permissions. All code is granted the minimal set of web |
| component permissions (which is a superset of the EJB minimal set). Do |
| not modify these entries. |
| |
| A few permissions above the minimal set are also granted in the default |
| `server.policy` file. These are necessary due to various internal |
| dependencies of the server implementation. Jakarta EE application |
| developers must not rely on these additional permissions. In some cases, |
| deleting these permissions might be appropriate. For example, one |
| additional permission is granted specifically for using connectors. If |
| connectors are not used in a particular domain, you should remove this |
| permission, because it is not otherwise necessary. |
| |
| [[gilzz]][[GSDVG00371]][[system-properties]] |
| |
| ==== System Properties |
| |
| The following predefined system properties, also called variables, are |
| available for use in the `server.policy` file. The system property most |
| frequently used in `server.policy` is `${com.sun.aas.instanceRoot}`. For |
| more information about system properties, see the |
| `asadmin create-system-properties` command in the link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| [[GSDVG533]][[sthref5]][[sthref6]] |
| |
| |
| Table 4-1 Predefined System Properties |
| |
| [width="100%",cols="29%,17%,54%",options="header",] |
| |=== |
| |Property |Default |Description |
| |`com.sun.aas.installRoot` |depends on operating system |Specifies the |
| directory where the {productName} is installed. |
| |
| |`com.sun.aas.instanceRoot` |depends on operating system |Specifies the |
| top level directory for a server instance. |
| |
| |`com.sun.aas.hostName` |none |Specifies the name of the host (machine). |
| |
| |`com.sun.aas.javaRoot` |depends on operating system |Specifies the |
| installation directory for the Java runtime. |
| |
| |`com.sun.aas.imqLib` |depends on operating system |Specifies the |
| library directory for the Open Message Queue software. |
| |
| |`com.sun.aas.configName` |`server-config` |Specifies the name of the |
| configuration used by a server instance. |
| |
| |`com.sun.aas.instanceName` |`server1` |Specifies the name of the server |
| instance. This property is not used in the default configuration, but |
| can be used to customize configuration. |
| |
| |`com.sun.aas.clusterName` |`cluster1` |Specifies the name of the |
| cluster. This property is only set on clustered server instances. This |
| property is not used in the default configuration, but can be used to |
| customize configuration. |
| |
| |`com.sun.aas.domainName` |`domain1` |Specifies the name of the domain. |
| This property is not used in the default configuration, but can be used |
| to customize configuration. |
| |=== |
| |
| |
| [[beabz]][[GSDVG00372]][[changing-permissions-for-an-application]] |
| |
| ==== Changing Permissions for an Application |
| |
| The default policy for each domain limits the permissions of Jakarta EE |
| deployed applications to the minimal set of permissions required for |
| these applications to operate correctly. Do not add extra permissions to |
| the default set (the grant block with no codebase, which applies to all |
| code). Instead, add a new grant block with a codebase specific to the |
| applications requiring the extra permissions, and only add the minimally |
| necessary permissions in that block. |
| |
| If you develop multiple applications that require more than this default |
| set of permissions, you can add the custom permissions that your |
| applications need. The `com.sun.aas.instanceRoot` variable refers to the |
| domain-dir. For example: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/-" { |
| ... |
| } |
| ---- |
| |
| You can add permissions to stub code with the following grant block: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/generated/-" { |
| ... |
| } |
| ---- |
| |
| In general, you should add extra permissions only to the applications or |
| modules that require them, not to all applications deployed to a domain. |
| For example: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/MyApp/-" { |
| ... |
| } |
| ---- |
| |
| For a module: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/MyModule/-" { |
| ... |
| } |
| ---- |
| |
| |
| [NOTE] |
| ==== |
| Deployment directories may change between {productName} releases. |
| ==== |
| |
| |
| An alternative way to add permissions to a specific application or |
| module is to edit the `granted.policy` file for that application or |
| module. The `granted.policy` file is located in the |
| domain-dir`/generated/policy/`app-or-module-name directory. In this |
| case, you add permissions to the default grant block. Do not delete |
| permissions from this file. |
| |
| When the {productName} policy subsystem determines that a permission |
| should not be granted, it logs a `server.policy` message specifying the |
| permission that was not granted and the protection domains, with |
| indicated code source and principals that failed the protection check. |
| For example, here is the first part of a typical message: |
| |
| [source] |
| ---- |
| [#|2005-12-17T16:16:32.671-0200|INFO|sun-appserver-pe9.1| |
| javax.enterprise.system.core.security|_ThreadID=14;_ThreadName=Thread-31;| |
| JACC Policy Provider: PolicyWrapper.implies, context(null)- |
| permission((java.util.PropertyPermission java.security.manager write)) |
| domain that failed(ProtectionDomain |
| (file:/E:/glassfish/domains/domain1/applications/cejug-clfds/ ... ) |
| ... |
| ---- |
| |
| Granting the following permission eliminates the message: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/cejug-clfds/-" { |
| permission java.util.PropertyPermission "java.security.manager", "write"; |
| } |
| ---- |
| |
| |
| [NOTE] |
| ==== |
| Do not add `java.security.AllPermission` to the `server.policy` file for |
| application code. Doing so completely defeats the purpose of the |
| security manager, yet you still get the performance overhead associated |
| with it. |
| ==== |
| |
| |
| As noted in the Jakarta EE specification, an application should provide |
| documentation of the additional permissions it needs. If an application |
| requires extra permissions but does not document the set it needs, |
| contact the application author for details. |
| |
| As a last resort, you can iteratively determine the permission set an |
| application needs by observing `AccessControlException` occurrences in |
| the server log. |
| |
| If this is not sufficient, you can add the |
| `-Djava.security.debug=failure` JVM option to the domain. Use the |
| following `asadmin create-jvm-options` command, then restart the server: |
| |
| [source] |
| ---- |
| asadmin create-jvm-options -Djava.security.debug=failure |
| ---- |
| |
| For more information about the `asadmin create-jvm-options` command, see |
| the link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| You can use the J2SE standard `policytool` or any text editor to edit |
| the `server.policy` file. For more information, see |
| `http://docs.oracle.com/javase/tutorial/security/tour2/index.html`. |
| |
| For detailed information about policy file syntax, see |
| `http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html`. |
| |
| For information about using system properties in the `server.policy` |
| file, see |
| `http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html`. |
| |
| For detailed information about the permissions you can set in the |
| `server.policy` file, see |
| `http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html`. |
| |
| The Javadoc for the `Permission` class is at |
| `http://docs.oracle.com/javase/8/docs/api/java/security/Permission.html`. |
| |
| [[gbyah]][[GSDVG00373]][[enabling-and-disabling-the-security-manager]] |
| |
| ==== Enabling and Disabling the Security Manager |
| |
| The security manager is disabled by default. |
| |
| In a production environment, you may be able to safely disable the |
| security manager if all of the following are true: |
| |
| * Performance is critical |
| * Deployment to the production server is carefully controlled |
| * Only trusted applications are deployed |
| * Applications don't need policy enforcement |
| |
| Disabling the security manager may improve performance significantly for |
| some types of applications. |
| |
| To enable the security manager, do one of the following: |
| |
| * To use the Administration Console, open the Security component under |
| the relevant configuration, and check the Security Manager Enabled box. |
| Then restart the server. For details, click the Help button in the |
| Administration Console. |
| * Use the following `asadmin create-jvm-options` command, then restart |
| the server: |
| + |
| [source] |
| ---- |
| asadmin create-jvm-options -Djava.security.manager |
| ---- |
| |
| To disable the security manager, uncheck the Security Manager Enabled |
| box or use the corresponding `asadmin delete-jvm-options` command. For |
| more information about `create-jvm-options` and `delete-jvm-options`, |
| see the link:reference-manual.html#GSRFM[{productName} Reference |
| Manual]. |
| |
| If the security manager is enabled and you are using the Java |
| Persistence API by calling `Persistence.createEMF()`, the EclipseLink |
| persistence provider requires that you set the |
| `eclipselink.security.usedoprivileged` JVM option to `true` as follows: |
| |
| [source] |
| ---- |
| asadmin create-jvm-options -Declipselink.security.usedoprivileged=true |
| ---- |
| |
| If the security manager is enabled and you are using the Java |
| Persistence API by injecting or looking up an entity manager or entity |
| manager factory, the EJB container sets this JVM option for you. |
| |
| You must grant additional permissions to CDI-enabled Jakarta EE |
| applications that are deployed in a {productName} 7 domain or |
| cluster for which security manager is enabled. These additional |
| permissions are not required when security manager is disabled. |
| |
| To deploy CDI-enabled Jakarta EE applications in a {productName} 7 |
| domain or cluster for which security manager is enabled, add the |
| following permissions to the applications: |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/[ApplicationName]" { |
| permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; |
| }; |
| ---- |
| |
| For example, for a CDI application named `foo.war`, add the following |
| permissions to the `server.policy` file, restart the domain or cluster, |
| and then deploy and use the application. |
| |
| [source] |
| ---- |
| grant codeBase "file:${com.sun.aas.instanceRoot}/applications/foo" { |
| permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; |
| }; |
| ---- |
| |
| For more information about modifying application permissions, see |
| link:#beabz[Changing Permissions for an Application]. |
| |
| [[beaca]][[GSDVG00122]][[configuring-message-security-for-web-services]] |
| |
| === Configuring Message Security for Web Services |
| |
| In message security, security information is applied at the message |
| layer and travels along with the web services message. Web Services |
| Security (WSS) is the use of XML Encryption and XML Digital Signatures |
| to secure messages. WSS profiles the use of various security tokens |
| including X.509 certificates, Security Assertion Markup Language (SAML) |
| assertions, and username/password tokens to achieve this. |
| |
| Message layer security differs from transport layer security in that it |
| can be used to decouple message protection from message transport so |
| that messages remain protected after transmission, regardless of how |
| many hops they travel. |
| |
| |
| [NOTE] |
| ==== |
| Message security (JSR 196) is supported only in the full {productName}, not in the Web Profile. |
| ==== |
| |
| |
| |
| [NOTE] |
| ==== |
| In this release of the {productName}, message layer annotations are |
| not supported. |
| ==== |
| |
| |
| For more information about web services, see |
| link:webservices.html#gaszn[Developing Web Services]. |
| |
| For more information about message security, see the following: |
| |
| * "https://eclipse-ee4j.github.io/jakartaee-tutorial/#security-2[Introduction to |
| Security in the Jakarta EE Platform]" in The Jakarta EE Tutorial |
| * link:security-guide.html#GSSCG[{productName} Security Guide] |
| * http://www.jcp.org/en/jsr/detail?id=196[JSR 196] |
| (`http://www.jcp.org/en/jsr/detail?id=196`), Java Authentication Service |
| Provider Interface for Containers |
| * The Liberty Alliance Project specifications at |
| `http://www.projectliberty.org/resources/specifications.php/?f=resources/specifications.php` |
| * The Oasis Web Services Security (WSS) specification at |
| `http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf` |
| * The Web Services Interoperability Organization (WS-I) Basic Security |
| Profile (BSP) specification at |
| `http://www.ws-i.org/Profiles/BasicSecurityProfile-1.0.html` |
| * The XML and Web Services Security page at `http://xwss.java.net/` |
| * The WSIT page at `http://wsit.java.net/` |
| |
| The following topics are addressed here: |
| |
| * link:#gbjxw[Message Security Providers] |
| * link:#beacb[Message Security Responsibilities] |
| * link:#beacf[Application-Specific Message Protection] |
| * link:#beaci[Understanding and Running the Sample Application] |
| |
| [[gbjxw]][[GSDVG00374]][[message-security-providers]] |
| |
| ==== Message Security Providers |
| |
| When you first install the {productName}, the providers |
| `XWS_ClientProvider` and `XWS_ServerProvider` are configured but |
| disabled. You can enable them in one of the following ways: |
| |
| * To enable the message security providers using the Administration |
| Console, open the Security component under the relevant configuration, |
| select the Message Security component, and select SOAP. Then select |
| `XWS_ServerProvider` from the Default Provider list and |
| `XWS_ClientProvider` from the Default Client Provider list. For details, |
| click the Help button in the Administration Console. |
| * You can enable the message security providers using the following |
| commands. |
| + |
| [source] |
| ---- |
| asadmin set |
| server-config.security-service.message-security-config.SOAP.default_provider=XWS_ServerProvider |
| asadmin set |
| server-config.security-service.message-security-config.SOAP.default_client_provider=XWS_ClientProvider |
| ---- |
| For more information about the `asadmin set` command, see the |
| link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| The example described in link:#beaci[Understanding and Running the |
| Sample Application] uses the `ClientProvider` and `ServerProvider` |
| providers, which are enabled when the Ant targets are run. You don't |
| need to enable these on the {productName} prior to running the |
| example. |
| |
| If you install the OpenSSO, you have these additional provider choices: |
| |
| * `AMClientProvider` and `AMServerProvider` - These providers secure web |
| services and Simple Object Access Protocol (SOAP) messages using either |
| WS-I BSP or Liberty ID-WSF tokens. These providers are used |
| automatically if they are configured as the default providers. If you |
| wish to override any provider settings, you can configure these |
| providers in `message-security-binding` elements in the |
| `glassfish-web.xml`, `glassfish-ejb-jar.xml`, and |
| `glassfish-application-client.xml` deployment descriptor files. |
| * `AMHttpProvider` - This provider handles the initial end user |
| authentication for securing web services using Liberty ID-WSF tokens and |
| redirects requests to the OpenSSO for single sign-on. To use this |
| provider, specify it in the `httpservlet-security-provider` attribute of |
| the `glassfish-web-app` element in the `glassfish-web.xml` file. |
| |
| Liberty specifications can be viewed at |
| `http://www.projectliberty.org/resources/specifications.php/?f=resources/specifications.php`. |
| The WS-I BSP specification can be viewed at |
| `http://www.ws-i.org/Profiles/BasicSecurityProfile-1.0.html`. |
| |
| For more information about the {productName} deployment descriptor |
| files, see the link:application-deployment-guide.html#GSDPG[{productName} |
| Application Deployment Guide]. |
| |
| For information about configuring these providers in the {productName}, see the link:security-guide.html#GSSCG[{productName} |
| Security Guide]. For additional information about overriding provider |
| settings, see link:#beacf[Application-Specific Message Protection]. |
| |
| You can create new message security providers in one of the following |
| ways: |
| |
| * To create a message security provider using the Administration |
| Console, open the Security component under the relevant configuration, |
| and select the Message Security component. For details, click the Help |
| button in the Administration Console. |
| * You can use the `asadmin create-message-security-provider` command to |
| create a message security provider. For details, see the |
| link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| In addition, you can set a few optional provider properties using the |
| `asadmin set` command. For example: |
| |
| [source] |
| ---- |
| asadmin set server-config.security-service.message-security-config.provider-config.property.debug=true |
| ---- |
| |
| The following table describes these message security provider |
| properties. |
| |
| [[GSDVG534]][[sthref7]][[sthref8]] |
| |
| |
| Table 4-2 Message Security Provider Properties |
| |
| [width="100%",cols="30%,24%,46%",options="header",] |
| |=== |
| |Property |Default |Description |
| |`security.config` |
| |domain-dir`/``config/``wss-server-``config-1.0.xml` |
| a|Specifies the location of the message security configuration file. To |
| point to a configuration file in the domain-dir``/config`` directory, use |
| the system property `${com.sun.aas.instanceRoot}/``config/`, for |
| example: |
| |
| `${com.sun.aas.instanceRoot}/config/``wss-server-config-1.0.xml` |
| |
| See link:#gilzz[System Properties]. |
| |
| |`debug` |
| |`false` |
| |If `true`, enables dumping of server provider debug messages to the server log. |
| |
| |`dynamic.username.password` |
| |`false` |
| |If `true`, signals the provider runtime to collect the user name and password from the `CallbackHandler` |
| for each request. |
| If `false`, the user name and password for `wsse:UsernameToken(s)` is collected once, during module initialization. |
| This property is only applicable for a `ClientAuthModule`. |
| |
| |`encryption.key.alias` |
| |`s1as` |
| |Specifies the encryption key used by the provider. The key is identified by its `keystore` alias. |
| |
| |`signature.key.alias` |
| |`s1as` |
| |Specifies the signature key used by the provider. The key is identified by its `keystore` alias. |
| |=== |
| |
| |
| [[beacb]][[GSDVG00375]][[message-security-responsibilities]] |
| |
| ==== Message Security Responsibilities |
| |
| In the {productName}, the system administrator and application |
| deployer roles are expected to take primary responsibility for |
| configuring message security. In some situations, the application |
| developer may also contribute, although in the typical case either of |
| the other roles may secure an existing application without changing its |
| implementation and without involving the developer. |
| |
| The following topics are addressed here: |
| |
| * link:#beacc[Application Developer Responsibilities] |
| * link:#beacd[Application Deployer Responsibilities] |
| * link:#beace[System Administrator Responsibilities] |
| |
| [[beacc]][[GSDVG00241]][[application-developer-responsibilities]] |
| |
| ===== Application Developer Responsibilities |
| |
| The application developer can turn on message security, but is not |
| responsible for doing so. Message security can be set up by the system |
| administrator so that all web services are secured, or set up by the |
| application deployer when the provider or protection policy bound to the |
| application must be different from that bound to the container. |
| |
| The application developer is responsible for the following: |
| |
| * Determining if an application-specific message protection policy is |
| required by the application. If so, ensuring that the required policy is |
| specified at application assembly which may be accomplished by |
| communicating with the application deployer. |
| * Determining if message security is necessary at the {productName} |
| level. If so, ensuring that this need is communicated to the system |
| administrator, or taking care of implementing message security at the |
| {productName} level. |
| |
| [[beacd]][[GSDVG00242]][[application-deployer-responsibilities]] |
| |
| ===== Application Deployer Responsibilities |
| |
| The application deployer is responsible for the following: |
| |
| * Specifying (at application assembly) any required application-specific |
| message protection policies if such policies have not already been |
| specified by upstream roles (the developer or assembler) |
| * Modifying {productName} deployment descriptors to specify |
| application-specific message protection policies information |
| (message-security-binding elements) to web service endpoint and service |
| references |
| |
| These security tasks are discussed in link:#beacf[Application-Specific |
| Message Protection]. A sample application using message security is |
| discussed in link:#beaci[Understanding and Running the Sample |
| Application]. |
| |
| [[beace]][[GSDVG00243]][[system-administrator-responsibilities]] |
| |
| ===== System Administrator Responsibilities |
| |
| The system administrator is responsible for the following: |
| |
| * Configuring message security providers on the {productName}. |
| * Managing user databases. |
| * Managing keystore and truststore files. |
| * Installing the sample. This is only done if the `xms` sample |
| application is used to demonstrate the use of message layer web services |
| security. |
| |
| A system administrator uses the Administration Console to manage server |
| security settings and uses a command line tool to manage certificate |
| databases. Certificates and private keys are stored in key stores and |
| are managed with `keytool`. If Network Security Services (NSS) is |
| installed, certificates and private keys are stored in an NSS database, |
| where they are managed using `certutil`. System administrator tasks are |
| discussed in the link:security-guide.html#GSSCG[{productName} |
| Security Guide]. |
| |
| [[beacf]][[GSDVG00376]][[application-specific-message-protection]] |
| |
| ==== Application-Specific Message Protection |
| |
| When the {productName} provided configuration is insufficient for |
| your security needs, and you want to override the default protection, |
| you can apply application-specific message security to a web service. |
| |
| Application-specific security is implemented by adding the message |
| security binding to the web service endpoint, whether it is an EJB or |
| servlet web service endpoint. Modify {productName} XML files to add |
| the message binding information. |
| |
| Message security can also be specified using a WSIT security policy in |
| the WSDL file. For details, see the WSIT page at |
| `http://wsit.java.net/`. |
| |
| For more information about message security providers, see |
| link:#gbjxw[Message Security Providers]. |
| |
| For more details on message security binding for EJB web services, |
| servlet web services, and clients, see the XML file descriptions in |
| "link:application-deployment-guide/dd-elements.html#GSDPG00007[Elements of the {productName} Deployment |
| Descriptors]" in {productName} Application |
| Deployment Guide. |
| |
| * For `glassfish-ejb-jar.xml`, see "link:application-deployment-guide/dd-files.html#GSDPG00079[The |
| glassfish-ejb-jar.xml File]" in {productName} |
| Application Deployment Guide. |
| * For `glassfish-web.xml`, see "link:application-deployment-guide/dd-files.html#GSDPG00078[The glassfish-web.xml |
| File]" in {productName} Application Deployment |
| Guide. |
| * For `glassfish-application-client.xml`, see "link:application-deployment-guide/dd-files.html#GSDPG00081[The |
| glassfish-application-client.xml file]" in {productName} Application Deployment Guide. |
| |
| The following topics are addressed here: |
| |
| * link:#beacg[Using a Signature to Enable Message Protection for All |
| Methods] |
| * link:#beach[Configuring Message Protection for a Specific Method Based |
| on Digital Signatures] |
| |
| [[beacg]][[GSDVG00244]][[using-a-signature-to-enable-message-protection-for-all-methods]] |
| |
| ===== Using a Signature to Enable Message Protection for All Methods |
| |
| To enable message protection for all methods using digital signature, |
| update the `message-security-binding` element for the EJB web service |
| endpoint in the application's `glassfish-ejb-jar.xml` file. In this |
| file, add `request-protection` and `response-protection` elements, which |
| are analogous to the `request-policy` and `response-policy` elements |
| discussed in the link:security-guide.html#GSSCG[{productName} |
| Security Guide]. To apply the same protection mechanisms for all |
| methods, leave the method-name element blank. link:#beach[Configuring |
| Message Protection for a Specific Method Based on Digital Signatures] |
| discusses listing specific methods or using wildcard characters. |
| |
| This section uses the sample application discussed in |
| link:#beaci[Understanding and Running the Sample Application] to apply |
| application-level message security to show only the differences |
| necessary for protecting web services using various mechanisms. |
| |
| [[fvyag]][[GSDVG00052]][[to-enable-message-protection-for-all-methods-using-digital-signature]] |
| |
| To Enable Message Protection for All Methods Using Digital Signature |
| |
| Follow this procedure. |
| |
| 1. In a text editor, open the application's `glassfish-ejb-jar.xml` |
| file. |
| + |
| For the `xms` example, this file is located in the directory |
| app-dir`/xms-ejb/src/conf`, where app-dir is defined in link:#beacj[To |
| Set Up the Sample Application]. |
| 2. Modify the `glassfish-ejb-jar.xml` file by adding the |
| `message-security-binding` element as shown: |
| + |
| [source,xml] |
| ---- |
| <glassfish-ejb-jar> |
| <enterprise-beans> |
| <unique-id>1</unique-id> |
| <ejb> |
| <ejb-name>HelloWorld</ejb-name> |
| <jndi-name>HelloWorld</jndi-name> |
| <webservice-endpoint> |
| <port-component-name>HelloIF</port-component-name> |
| <endpoint-address-uri>service/HelloWorld</endpoint-address-uri> |
| <message-security-binding auth-layer="SOAP"> |
| <message-security> |
| <request-protection auth-source="content" /> |
| <response-protection auth-source="content"/> |
| </message-security> |
| </message-security-binding> |
| </webservice-endpoint> |
| </ejb> |
| </enterprise-beans> |
| </glassfish-ejb-jar> |
| ---- |
| 3. Compile, deploy, and run the application as described in |
| link:#beack[To Run the Sample Application]. |
| |
| [[beach]][[GSDVG00245]][[configuring-message-protection-for-a-specific-method-based-on-digital-signatures]] |
| |
| ===== Configuring Message Protection for a Specific Method Based on Digital Signatures |
| |
| To enable message protection for a specific method, or for a set of |
| methods that can be identified using a wildcard value, follow these |
| steps. As in the example discussed in link:#beacg[Using a Signature to |
| Enable Message Protection for All Methods], to enable message protection |
| for a specific method, update the `message-security-binding` element for |
| the EJB web service endpoint in the application's |
| `glassfish-ejb-jar.xml` file. To this file, add `request-protection` and |
| `response-protection` elements, which are analogous to the |
| `request-policy` and `response-policy` elements discussed in the |
| link:security-guide.html#GSSCG[{productName} Security Guide]. The |
| administration guide includes a table listing the set and order of |
| security operations for different request and response policy |
| configurations. |
| |
| This section uses the sample application discussed in |
| link:#beaci[Understanding and Running the Sample Application] to apply |
| application-level message security to show only the differences |
| necessary for protecting web services using various mechanisms. |
| |
| [[fvybb]][[GSDVG00053]][[to-enable-message-protection-for-a-particular-method-or-set-of-methods-using-digital-signature]] |
| |
| To Enable Message Protection for a Particular Method or Set of Methods |
| Using Digital Signature |
| |
| Follow this procedure. |
| |
| 1. In a text editor, open the application's `glassfish-ejb-jar.xml` |
| file. |
| + |
| For the `xms` example, this file is located in the directory |
| app-dir`/xms-ejb/src/conf`, where app-dir is defined in link:#beacj[To |
| Set Up the Sample Application]. |
| 2. Modify the `glassfish-ejb-jar.xml` file by adding the |
| `message-security-binding` element as shown: |
| + |
| [source,xml] |
| ---- |
| <glassfish-ejb-jar> |
| <enterprise-beans> |
| <unique-id>1</unique-id> |
| <ejb> |
| <ejb-name>HelloWorld</ejb-name> |
| <jndi-name>HelloWorld</jndi-name> |
| <webservice-endpoint> |
| <port-component-name>HelloIF</port-component-name> |
| <endpoint-address-uri>service/HelloWorld</endpoint-address-uri> |
| <message-security-binding auth-layer="SOAP"> |
| <message-security> |
| <message> |
| <java-method> |
| <method-name>ejbCreate</method-name> |
| </java-method> |
| </message> |
| <message> |
| <java-method> |
| <method-name>sayHello</method-name> |
| </java-method> |
| </message> |
| <request-protection auth-source="content" /> |
| <response-protection auth-source="content"/> |
| </message-security> |
| </message-security-binding> |
| </webservice-endpoint> |
| </ejb> |
| </enterprise-beans> |
| </glassfish-ejb-jar> |
| ---- |
| 3. Compile, deploy, and run the application as described in |
| link:#beack[To Run the Sample Application]. |
| |
| [[beaci]][[GSDVG00377]][[understanding-and-running-the-sample-application]] |
| |
| ==== Understanding and Running the Sample Application |
| |
| This section discusses the WSS sample application. This sample |
| application is installed on your system only if you installed the J2EE |
| 1.4 samples. If you have not installed these samples, see link:#beacj[To |
| Set Up the Sample Application]. |
| |
| The objective of this sample application is to demonstrate how a web |
| service can be secured with WSS. The web service in the `xms` example is |
| a simple web service implemented using a Jakarta EE EJB endpoint and a web |
| service endpoint implemented using a servlet. In this example, a service |
| endpoint interface is defined with one operation, `sayHello`, which |
| takes a string then sends a response with `Hello` prefixed to the given |
| string. You can view the WSDL file for the service endpoint interface at |
| app-dir`/xms-ejb/src/``conf/HelloWorld.wsdl`, where app-dir is defined |
| in link:#beacj[To Set Up the Sample Application]. |
| |
| In this application, the client looks up the service using the JNDI name |
| `java:comp/env/service/HelloWorld` and gets the port information using a |
| static stub to invoke the operation using a given name. For the name |
| Duke, the client gets the response `Hello Duke!` |
| |
| This example shows how to use message security for web services at the |
| {productName} level. For information about using message security at |
| the application level, see link:#beacf[Application-Specific Message |
| Protection]. The WSS message security mechanisms implement message-level |
| authentication (for example, XML digital signature and encryption) of |
| SOAP web services invocations using the X.509 and username/password |
| profiles of the OASIS WS-Security standard, which can be viewed from the |
| following URL: |
| `http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf`. |
| |
| The following topics are addressed here: |
| |
| * link:#beacj[To Set Up the Sample Application] |
| * link:#beack[To Run the Sample Application] |
| |
| [[beacj]][[GSDVG00054]][[to-set-up-the-sample-application]] |
| |
| ===== To Set Up the Sample Application |
| |
| [[GSDVG535]] |
| |
| Before You Begin |
| |
| To have access to this sample application, you must have previously |
| installed the J2EE 1.4 samples. If the samples are not installed, follow |
| the steps in the following section. |
| |
| After you follow these steps, the sample application is located in the |
| directory |
| as-install``/j2ee14-samples/samples/webservices/security/ejb/apps/xms/`` |
| or in a directory of your choice. For easy reference throughout the rest |
| of this section, this directory is referred to as simply app-dir. |
| |
| 1. Go to the |
| http://www.oracle.com/technetwork/java/javaee/download-141771.html[J2EE |
| 1.4 download URL] |
| (`http://www.oracle.com/technetwork/java/javaee/download-141771.html`) |
| in your browser. |
| 2. Click on the Download button for the Samples Bundle. |
| 3. Click on Accept License Agreement. |
| 4. Click on the J2EE SDK Samples link. |
| 5. Choose a location for the `j2eesdk-1_4_03-samples.zip` file. |
| + |
| Saving the file to as-install is recommended. |
| 6. Unzip the file. |
| + |
| Unzipping to the as-install``/j2ee14-samples`` directory is recommended. |
| For example, you can use the following command. |
| + |
| [source] |
| ---- |
| unzip j2eesdk-1_4_03-samples.zip -d j2ee14-samples |
| ---- |
| |
| [[beack]][[GSDVG00055]][[to-run-the-sample-application]] |
| |
| ===== To Run the Sample Application |
| |
| 1. Make sure that the {productName} is running. + |
| Message security providers are set up when the Ant targets are run, so |
| you do not need to configure these on the {productName} prior to |
| running this example. |
| |
| 2. If you are not running HTTP on the default port of 8080, change the |
| WSDL file for the example to reflect the change, and change the |
| `common.properties` file to reflect the change as well. + |
| The WSDL file for this example is located at |
| app-dir`/xms-ejb/``src/conf/HelloWorld.wsdl`. The port number is in the |
| following section: |
| + |
| [source,xml] |
| ---- |
| <service name="HelloWorld"> |
| <port name="HelloIFPort" binding="tns:HelloIFBinding"> |
| <soap:address location="http://localhost:8080/service/HelloWorld"/> |
| </port> |
| </service> |
| ---- |
| Verify that the properties in the as-install``/samples/common.properties` |
| file are set properly for your installation and environment. If you need |
| a more detailed description of this file, refer to the "Configuration" |
| section for the web services security applications at |
| as-install``/j2ee14-samples/samples/webservices/security/docs/common.html#Logging`. |
| |
| 3. Change to the app-dir directory. |
| |
| 4. Run the following Ant targets to compile, deploy, and run the |
| example application: |
| [arabic] |
| .. To compile samples: `ant` |
| .. To deploy samples: `ant deploy` |
| .. To run samples: `ant run` |
| |
| + |
| If the sample has compiled and deployed properly, you see the following |
| response on your screen after the application has run: + |
| `run:[echo] Running the xms program:[exec] Established message level security : Hello Duke!` |
| |
| 5. To undeploy the sample, run the following Ant target: |
| + |
| [source] |
| ---- |
| ant undeploy |
| ---- |
| |
| All of the web services security examples use the same web service name |
| (`HelloWorld`) and web service ports. These examples show only the |
| differences necessary for protecting web services using various |
| mechanisms. Make sure to undeploy an application when you have completed |
| running it. If you do not, you receive an `Already in Use` error and |
| deployment failures when you try to deploy another web services example |
| application. |
| |
| [[beacm]][[GSDVG00123]][[programmatic-login-using-the-programmaticlogin-class]] |
| |
| === Programmatic Login Using the ProgrammaticLogin Class |
| |
| Programmatic login allows a deployed Jakarta EE application or module to |
| invoke a login method. If the login is successful, a `SecurityContext` |
| is established as if the client had authenticated using any of the |
| conventional Jakarta EE mechanisms. Programmatic login is supported for |
| servlet and EJB components on the server side, and for stand-alone or |
| application clients on the client side. Programmatic login is useful for |
| an application having special needs that cannot be accommodated by any |
| of the Jakarta EE standard authentication mechanisms. |
| |
| This section describes a proprietary GlassFish mechanism, but see also |
| the standard security APIs in the Jakarta EE tutorial. |
| |
| |
| [NOTE] |
| ==== |
| The `com.sun.appserv.security.ProgrammaticLogin` class in {productName} is not a Jakarta EE API; therefore, it is not portable to other |
| application servers. |
| ==== |
| |
| |
| The following topics are addressed here: |
| |
| * link:#beacn[Programmatic Login Precautions] |
| * link:#beaco[Granting Programmatic Login Permission] |
| * link:#beacp[The `ProgrammaticLogin` Class] |
| |
| [[beacn]][[GSDVG00378]][[programmatic-login-precautions]] |
| |
| ==== Programmatic Login Precautions |
| |
| The {productName} is not involved in how the login information |
| (`user`, `password`) is obtained by the deployed application. |
| Programmatic login places the burden on the application developer with |
| respect to assuring that the resulting system meets security |
| requirements. If the application code reads the authentication |
| information across the network, the application determines whether to |
| trust the user. |
| |
| Programmatic login allows the application developer to bypass the |
| {productName}-supported authentication mechanisms and feed |
| authentication data directly to the security service. While flexible, |
| this capability should not be used without some understanding of |
| security issues. |
| |
| Since this mechanism bypasses the container-managed authentication |
| process and sequence, the application developer must be very careful in |
| making sure that authentication is established before accessing any |
| restricted resources or methods. It is also the application developer's |
| responsibility to verify the status of the login attempt and to alter |
| the behavior of the application accordingly. |
| |
| The programmatic login state does not necessarily persist in sessions or |
| participate in single sign-on. |
| |
| Lazy authentication is not supported for programmatic login. If an |
| access check is reached and the deployed application has not properly |
| authenticated using the programmatic login method, access is denied |
| immediately and the application might fail if not coded to account for |
| this occurrence. One way to account for this occurrence is to catch the |
| access control or security exception, perform a programmatic login, and |
| repeat the request. |
| |
| [[beaco]][[GSDVG00379]][[granting-programmatic-login-permission]] |
| |
| ==== Granting Programmatic Login Permission |
| |
| The `ProgrammaticLoginPermission` permission is required to invoke the |
| programmatic login mechanism for an application if the security manager |
| is enabled. For information about the security manager, see |
| link:#beabx[The `server.policy` File]. This permission is not granted by |
| default to deployed applications because this is not a standard Jakarta EE |
| mechanism. |
| |
| To grant the required permission to the application, add the following |
| to the domain-dir`/config/server.policy` file: |
| |
| [source] |
| ---- |
| grant codeBase "file:jar-file-path" { |
| permission com.sun.appserv.security.ProgrammaticLoginPermission |
| "login"; |
| }; |
| ---- |
| |
| The jar-file-path is the path to the application's JAR file. |
| |
| [[beacp]][[GSDVG00380]][[the-programmaticlogin-class]] |
| |
| ==== The `ProgrammaticLogin` Class |
| |
| The `com.sun.appserv.security.ProgrammaticLogin` class enables a user to |
| perform login programmatically. |
| |
| For Javadoc tool pages relevant to programmatic login, see the |
| `com.sun.appserv.security` package. |
| |
| The `ProgrammaticLogin` class has four `login` methods, two for servlets |
| or JSP files and two for EJB components. |
| |
| The login methods for servlets or JSP files have the following |
| signatures: |
| |
| [source,java] |
| ---- |
| public java.lang.Boolean login(String user, String password, |
| javax.servlet.http.HttpServletRequest request, |
| javax.servlet.http.HttpServletResponse response) |
| |
| public java.lang.Boolean login(String user, String password, |
| String realm, javax.servlet.http.HttpServletRequest request, |
| javax.servlet.http.HttpServletResponse response, boolean errors) |
| throws java.lang.Exception |
| ---- |
| |
| The login methods for EJB components have the following signatures: |
| |
| [source,java] |
| ---- |
| public java.lang.Boolean login(String user, String password) |
| |
| public java.lang.Boolean login(String user, String password, |
| String realm, boolean errors) throws java.lang.Exception |
| ---- |
| |
| All of these `login` methods accomplish the following: |
| |
| * Perform the authentication |
| * Return `true` if login succeeded, `false` if login failed |
| |
| The login occurs on the realm specified unless it is null, in which case |
| the domain's default realm is used. The methods with no realm parameter |
| use the domain's default realm. |
| |
| If the errors flag is set to `true`, any exceptions encountered during |
| the login are propagated to the caller. If set to `false`, exceptions |
| are thrown. |
| |
| On the client side, realm and errors parameters are ignored and the |
| actual login does not occur until a resource requiring a login is |
| accessed. A `java.rmi.AccessException` with `COBRA NO_PERMISSION` occurs |
| if the actual login fails. |
| |
| The logout methods for servlets or JSP files have the following |
| signatures: |
| |
| [source,java] |
| ---- |
| public java.lang.Boolean logout(HttpServletRequest request, |
| HttpServletResponse response) |
| |
| public java.lang.Boolean logout(HttpServletRequest request, |
| HttpServletResponse response, boolean errors) |
| throws java.lang.Exception |
| ---- |
| |
| The logout methods for EJB components have the following signatures: |
| |
| [source,java] |
| ---- |
| public java.lang.Boolean logout() |
| |
| public java.lang.Boolean logout(boolean errors) |
| throws java.lang.Exception |
| ---- |
| |
| All of these `logout` methods return `true` if logout succeeded, `false` |
| if logout failed. |
| |
| If the errors flag is set to `true`, any exceptions encountered during |
| the logout are propagated to the caller. If set to `false`, exceptions |
| are thrown. |
| |
| [[beacq]][[GSDVG00124]][[user-authentication-for-single-sign-on]] |
| |
| === User Authentication for Single Sign-on |
| |
| The single sign-on feature of the {productName} allows multiple web |
| applications deployed to the same virtual server to share the user |
| authentication state. With single sign-on enabled, users who log in to |
| one web application become implicitly logged into other web applications |
| on the same virtual server that require the same authentication |
| information. Otherwise, users would have to log in separately to each |
| web application whose protected resources they tried to access. |
| |
| A sample application using the single sign-on scenario could be a |
| consolidated airline booking service that searches all airlines and |
| provides links to different airline web sites. After the user signs on |
| to the consolidated booking service, the user information can be used by |
| each individual airline site without requiring another sign-on. |
| |
| Single sign-on operates according to the following rules: |
| |
| * Single sign-on applies to web applications configured for the same |
| realm and virtual server. The realm is defined by the `realm-name` |
| element in the `web.xml` file. For information about virtual servers, |
| see "link:administration-guide/http_https.html#GSADG00017[Administering Internet Connectivity]" in {productName} Administration Guide. |
| * As long as users access only unprotected resources in any of the web |
| applications on a virtual server, they are not challenged to |
| authenticate themselves. |
| * As soon as a user accesses a protected resource in any web application |
| associated with a virtual server, the user is challenged to authenticate |
| himself or herself, using the login method defined for the web |
| application currently being accessed. |
| * After authentication, the roles associated with this user are used for |
| access control decisions across all associated web applications, without |
| challenging the user to authenticate to each application individually. |
| * When the user logs out of one web application (for example, by |
| invalidating the corresponding session), the user's sessions in all web |
| applications are invalidated. Any subsequent attempt to access a |
| protected resource in any application requires the user to authenticate |
| again. |
| |
| The single sign-on feature utilizes HTTP cookies to transmit a token |
| that associates each request with the saved user identity, so it can |
| only be used in client environments that support cookies. |
| |
| To configure single sign-on, set the following virtual server |
| properties: |
| |
| * `sso-enabled` - If `false`, single sign-on is disabled for this |
| virtual server, and users must authenticate separately to every |
| application on the virtual server. The default is `false`. |
| * `sso-max-inactive-seconds` - Specifies the time after which a user's |
| single sign-on record becomes eligible for purging if no client activity |
| is received. Since single sign-on applies across several applications on |
| the same virtual server, access to any of the applications keeps the |
| single sign-on record active. The default value is 5 minutes (`300` |
| seconds). Higher values provide longer single sign-on persistence for |
| the users at the expense of more memory use on the server. |
| * `sso-reap-interval-seconds` - Specifies the interval between purges of |
| expired single sign-on records. The default value is `60`. |
| |
| Here are example `asadmin set` commands with default values: |
| |
| [source] |
| ---- |
| asadmin set server-config.http-service.virtual-server.vsrv1.property.sso-enabled="true" |
| asadmin set server-config.http-service.virtual-server.vsrv1.property.sso-max-inactive-seconds="300" |
| asadmin set server-config.http-service.virtual-server.vsrv1.property.sso-reap-interval-seconds="60" |
| ---- |
| |
| For more information about the `asadmin set` command, see the |
| link:reference-manual.html#GSRFM[{productName} Reference Manual]. |
| |
| [[gizel]][[GSDVG00125]][[adding-authentication-mechanisms-to-the-servlet-container]] |
| |
| === Adding Authentication Mechanisms to the Servlet Container |
| |
| You can use JSR 196 in the web tier to facilitate the injection of |
| pluggable authentication modules within the servlet constraint |
| processing engine. The {productName} includes implementations of a |
| number of HTTP layer authentication mechanisms such as basic, form, and |
| digest authentication. You can add alternative implementations of the |
| included mechanisms or implementations of new mechanisms such as HTTP |
| Negotiate/SPNEGO, OpenID, or CAS. |
| |
| The following topics are addressed here: |
| |
| * link:#BACCFGBF[The {productName} and JSR-375] |
| * link:#gizfz[The {productName} and JSR 196] |
| * link:#gizdx[Writing a Server Authentication Module] |
| * link:#gizeb[Sample Server Authentication Module] |
| * link:#gizfa[Compiling and Installing a Server Authentication Module] |
| * link:#gizfe[Configuring a Server Authentication Module] |
| * link:#gizfm[Binding a Server Authentication Module to Your |
| Application] |
| |
| [[BACCFGBF]][[GSDVG564]][[the-glassfish-server-and-jsr-375]] |
| |
| ==== The {productName} and JSR-375 |
| |
| The {productName} implements JSR-375 to provide built-in support for |
| BASIC, FORM and Custom FORM authentication mechanisms. JSR-375 also |
| defines plug-in interfaces for authentication and identity stores, that |
| is, the `HttpAuthenticationMechanism` interface and the `IdentityStore` |
| interface, respectively. Though `HttpAuthenticationMechanism` |
| implementations can authenticate users in any manner they choose, the |
| `IdentityStore` interface provides a convenient mechanism. A significant |
| advantage of using `HttpAuthenticationMechanism` and `IdentityStore` |
| over the declarative mechanisms defined by the Servlet specification is |
| that it allows an application to control the identity stores that it |
| authenticates against, in a standard, portable way. You can use the |
| built-in implementations of these APIs, or define custom |
| implementations. |
| |
| Jakarta EE Security API defines several annotations, with names that end |
| with Definition, which when used makes the corresponding built-in |
| mechanism available as a CDI bean. Jakarta EE Security API also supports |
| the use of Expression Language 3.0 in these annotations to allow dynamic |
| configuration. |
| |
| [[GSDVG565]][[sthref9]] |
| |
| |
| [[built-in-authentication-mechanisms]] |
| ===== Built-in Authentication Mechanisms |
| |
| An application packages its own `HttpAuthenticationMechanism` by |
| including in a bean archive that is a part of the application. |
| Alternatively, it may select and configure one of the container's |
| built-in mechanisms using the corresponding annotation, as listed below: |
| |
| * `BasicAuthenticationMechanismDefintion`—implements BASIC |
| authentication that conforms to the behavior of the servlet container |
| when BASIC <auth-method> is declared in web.xml. |
| * `CustomFormAuthenticationMechanismDefinition`—implements FORM |
| authentication that conforms to the behavior of the servlet container |
| when the FORM <auth-method> is declared in web.xml. |
| * `FormAuthenticationMechanismDefinition`—implements a modified version |
| of FORM authentication in which custom handling replaces the POST to |
| j_security_check. |
| |
| In {productName}, all built-in authentication mechanisms need to be |
| authenticated using an identity store. The `IdentityStore` interface, |
| included in the Jakarta EE Security API, defines an SPI for interacting |
| with identity stores, which are directories or databases containing user |
| account information. The `IdentityStore` interface has four methods: |
| `validate(Credential)`, `getCallerGroups(CredentialValidationResult)`, |
| `validationTypes()` and `priority()`.Developers can provide their own |
| implementation of this interface, or use one of the built-in Identity |
| Stores. The `RememberMeIdentityStore` interface, which is a variation on |
| the IdentityStore interface, can be used when an application wants to |
| "remember" a user's authenticated session for an extended period, so |
| that the caller can return to the application periodically without |
| needing to present primary authentication credentials each time. |
| |
| There are two built-in implementations of `IdentityStore`: an LDAP |
| identity store, and a Database identity store. The following snippet |
| shows the usage of `DatabaseIdentityStoreDefinition`, which makes |
| `DatabaseIdentityStore` available as CDI bean. |
| |
| [source,java] |
| ---- |
| @DatabaseIdentityStoreDefinition( |
| callerQuery = "#{'select password from caller where name = ?'}", |
| groupsQuery = "select group_name from caller_groups where caller_name = ?", |
| hashAlgorithm = Pbkdf2PasswordHash.class, |
| priorityExpression = "#{100}", |
| hashAlgorithmParameters = { |
| "Pbkdf2PasswordHash.Iterations=3072", |
| "${applicationConfig.dyna}" |
| } |
| ) |
| ---- |
| |
| Since Jakarta EE Security API provides support for Expression Langauge 3.0, |
| regular expressions can be used to set value of annotation attributes. |
| |
| The {productName} provides out of the box implementation of |
| `Pbkdf2PasswordHash` that supports PBKDF2 password hashing. It is |
| suggested that you use `Pbkdf2PasswordHash` for generating and |
| validating passwords, unless there are specific requirements which |
| cannot be met any other way. |
| |
| [[GSDVG566]][[sthref10]] |
| |
| |
| [[custom-authentication-mechanism]] |
| ===== Custom Authentication Mechanism |
| |
| An application provider can choose to provide its own custom |
| authentication mechanism, apart from built-in authentication mechanism. |
| |
| A custom authentication mechanism implements the |
| `HttpAuthenticationMechanism` interface, introduced in Jakarta EE Security |
| API. This interface defines the following three methods. |
| |
| [source,java] |
| ---- |
| AuthenticationStatus validateRequest(HttpServletRequest request, |
| HttpServletResponse response, |
| HttpMessageContext httpMessageContext |
| ) throws AuthenticationException; |
| |
| AuthenticationStatus secureResponse(HttpServletRequest request, |
| HttpServletResponse response, |
| HttpMessageContext httpMessageContext |
| ) throws AuthenticationException; |
| |
| void cleanSubject(HttpServletRequest request, |
| HttpServletResponse response, |
| HttpMessageContext httpMessageContext); |
| ---- |
| |
| `HttpAuthenticationMechanism` returns `AuthenticationStatus` to indicate |
| the status of authentication request. Internally, it gets translated to |
| corresponding JASPIC `AuthStatus` as shown below: |
| |
| * `AuthenticationStatus.NOT_DONE` to `AuthStatus.SUCCESS` |
| * `AuthenticationStatus.SEND_CONTINUE` to `AuthStatus.SEND_CONTINUE` |
| * `AuthenticationStatus.SUCCESS` to `AuthStatus.SUCCESS` |
| * `AuthenticationStatus.SEND_FAILURE` to `AuthStatus.SEND_FAILURE` |
| |
| Each method of the `HttpAuthenticationMechanism` interface performs the |
| same function as the corresponding `ServerAuth` methods. Unlike JASPIC, |
| `HttpAuthenticationMechanism` is specified for the servlet container |
| only. Only the `validateRequest()` must be implemented, for other two |
| methods, default behaviors are specified. |
| |
| `validateRequest` allows a caller to authenticate. The request gets |
| inspected inside `validateRequest` to read credential or any other |
| information, or it can write to standard response with status of the |
| authentication request or redirect the caller to an OAuth provider. Once |
| the credential is validated, the result of the validation is |
| communicated to the container using the `HttpMessageContext` parameter. |
| |
| [[GSDVG567]] |
| |
| Sample Http Authentication Mechanism |
| |
| The class `MyAuthenticationMechanism.java` is a sample |
| `HttpAuthenticationMechanism` implementation. Note that only |
| `validateRequest` method has been implemented, since Jakarta EE Security |
| API provides default implementation of other two methods. An application |
| provider may choose to override the default implementation depending on |
| the requirement. |
| |
| [source,java] |
| ---- |
| import javax.enterprise.context.RequestScoped; |
| import javax.inject.Inject; |
| import javax.security.enterprise.AuthenticationException; |
| import javax.security.enterprise.AuthenticationStatus; |
| import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism; |
| import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext; |
| import javax.security.enterprise.credential.UsernamePasswordCredential; |
| import javax.security.enterprise.identitystore.CredentialValidationResult; |
| import javax.security.enterprise.identitystore.IdentityStoreHandler; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID; |
| |
| @RequestScoped |
| public class MyAuthenticationMechanism implements HttpAuthenticationMechanism { |
| |
| @Inject |
| private IdentityStoreHandler identityStoreHandler; |
| |
| @Override |
| public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException { |
| |
| // Get the (caller) name and password from the request |
| // NOTE: This is for the smallest possible example only. In practice |
| // putting the password in a request query parameter is highly |
| // insecure and is discouraged. |
| String name = request.getParameter("name"); |
| String password = request.getParameter("password"); |
| |
| if (name != null && password != null) { |
| |
| // Delegate the {credentials in -> identity data out} function to |
| // the Identity Store |
| CredentialValidationResult result = identityStoreHandler.validate( |
| new UsernamePasswordCredential(name, password)); |
| |
| if (result.getStatus() == VALID) { |
| // Communicate the details of the authenticated user to the |
| // container. |
| response.addHeader("Authentication Mechanism", "MyAuthenticationMechanism"); |
| return httpMessageContext.notifyContainerAboutLogin( |
| result.getCallerPrincipal(), result.getCallerGroups()); |
| } else { |
| return httpMessageContext.responseUnauthorized(); |
| } |
| } |
| |
| return httpMessageContext.doNothing(); |
| } |
| |
| } |
| ---- |
| |
| [[gizfz]][[GSDVG00381]][[the-glassfish-server-and-jsr-196]] |
| |
| ==== The {productName} and JSR 196 |
| |
| The {productName} implements the Servlet Container Profile of JSR |
| 196, Java Authentication Service Provider Interface for Containers. JSR |
| 196 defines a standard service provider interface (SPI) that extends the |
| concepts of the Java Authentication and Authorization Service (JAAS) to |
| enable pluggability of message authentication modules in message |
| processing runtimes. The JSR 196 standard defines profiles that |
| establish contracts for the use of the SPI in specific contexts. The |
| Servlet Container Profile of JSR 196 defines the use of the SPI by a |
| Servlet container such that: |
| |
| * The resulting container can be configured with new authentication |
| mechanisms. |
| * The container employs the configured mechanisms in its enforcement of |
| the declarative servlet security model (declared in a `web.xml` file |
| using `security-constraint` elements). |
| |
| The JSR 196 specification defines a simple message processing model |
| composed of four interaction points: |
| |
| 1. `secureRequest` on the client |
| 2. `validateRequest` on the server |
| 3. `secureResponse` on the server |
| 4. `validateResponse` on the client |
| |
| A message processing runtime uses the SPI at these interaction points to |
| delegate the corresponding message security processing to authentication |
| providers, also called authentication modules, integrated into the |
| runtime by way of the SPI. |
| |
| A compatible server-side message processing runtime, such as the |
| {productName} servlet container, supports the `validateRequest` and |
| `secureResponse` interaction points of the message processing model. The |
| servlet container uses the SPI at these interaction points to delegate |
| the corresponding message security processing to a server authentication |
| module (SAM), integrated by the SPI into the container. |
| |
| [[gizdx]][[GSDVG00382]][[writing-a-server-authentication-module]] |
| |
| ==== Writing a Server Authentication Module |
| |
| A key step in adding an authentication mechanism to a compatible |
| server-side message processing runtime such as the {productName} |
| servlet container is acquiring a SAM that implements the desired |
| authentication mechanism. One way to do that is to write the SAM |
| yourself. |
| |
| A SAM implements the javax.security.auth.message.module.ServerAuthModule |
| interface as defined by JSR 196. A SAM is invoked indirectly by the |
| message processing runtime at the `validateRequest` and `secureResponse` |
| interaction points. A SAM must implement the five methods of the |
| ServerAuthModule interface: |
| |
| * `getSupportedMessageTypes` — An array of `Class` objects where each |
| element defines a message type supported by the SAM. For a SAM to be |
| compatible with the Servlet Container Profile, the returned array must |
| include the `HttpServletRequest.class` and `HttpServletResponse.class` |
| objects. |
| * `initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler Map options)` |
| — The container calls this method to provide the SAM with configuration |
| values and with a `CallbackHandler`. The configuration values are |
| returned in the policy arguments and in the options `Map`. The SAM uses |
| `CallbackHandler` to access services, such as password validation, |
| provided by the container. |
| * `AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)` |
| — The container calls this method to process each received |
| `HttpServletRequest`. The request and its associated |
| `HttpServletResponse` are passed by the container to the SAM in the |
| `messageInfo` argument. The SAM processes the request and may establish |
| the response to be returned by the container. The SAM uses the provided |
| `Subject` arguments to convey its authentication results. The SAM |
| returns different status values to control the container's invocation |
| processing. The status values and the circumstances under which they are |
| returned are as follows: |
| |
| ** `AuthStatus.SUCCESS` is returned when the application request message |
| is successfully validated. The container responds to this status value |
| by using the returned client `Subject` to invoke the target of the |
| request. When this value is returned, the SAM (provided a custom |
| `AuthConfigProvider` is not being used) must use its `CallbackHandler` |
| to handle a `CallerPrincipalCallback` using the `clientSubject` as an |
| argument to the callback. |
| |
| ** `AuthStatus.SEND_CONTINUE` indicates that message validation is |
| incomplete and that the SAM has established a preliminary response as |
| the response message in `messageInfo`. The container responds to this |
| status value by sending the response to the client. |
| |
| ** `AuthStatus.SEND_FAILURE` indicates that message validation failed |
| and that the SAM has established an appropriate failure response message |
| in `messageInfo`. The container responds to this status value by sending |
| the response to the client. |
| |
| ** `AuthStatus.SEND_SUCCESS` is not typically returned. This status |
| value indicates the end of a multi-message security dialog originating |
| after the service interaction and during the processing of the |
| application response. The container responds to this status value by |
| sending the response to the client. |
| + |
| The `validateRequest` method may also throw an `AuthException` to |
| indicate that the message processing by the SAM failed without |
| establishing a failure response message in `messageInfo`. |
| * `secureResponse(MessageInfo messageInfo, Subject serviceSubject)` — |
| The container calls this method before sending a response, resulting |
| from an application invocation, to the client. The response is passed to |
| the SAM in the `messageInfo` argument. In most cases, this method should |
| just return the `SEND_SUCCESS` status. |
| * `cleanSubject(MessageInfo messageInfo, Subject subject)` — This method |
| removes the mechanism-specific principals, credentials, or both from the |
| subject. This method is not currently called by the container. A |
| legitimate implementation could remove all the principals from the |
| argument subject. |
| |
| See the Servlet Container Profile section in the JSR 196 specification |
| for additional background and details. |
| |
| [[gizeb]][[GSDVG00383]][[sample-server-authentication-module]] |
| |
| ==== Sample Server Authentication Module |
| |
| The class `MySam.java` is a sample SAM implementation. Notice that the |
| sample implements the five methods of the ServerAuthModule interface. |
| This SAM implements an approximation of HTTP basic authentication. |
| |
| [source,java] |
| ---- |
| package tip.sam; |
| |
| import java.io.IOException; |
| import java.util.Map; |
| import javax.security.auth.Subject; |
| import javax.security.auth.callback.Callback; |
| import javax.security.auth.callback.CallbackHandler; |
| import javax.security.auth.callback.UnsupportedCallbackException; |
| import javax.security.auth.message.AuthException; |
| import javax.security.auth.message.AuthStatus; |
| import javax.security.auth.message.MessageInfo; |
| import javax.security.auth.message.MessagePolicy; |
| import javax.security.auth.message.callback.CallerPrincipalCallback; |
| import javax.security.auth.message.callback.GroupPrincipalCallback; |
| import javax.security.auth.message.callback.PasswordValidationCallback; |
| import javax.security.auth.message.module.ServerAuthModule; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import org.apache.catalina.util.Base64; |
| |
| public class MySam implements ServerAuthModule { |
| |
| protected static final Class[] |
| supportedMessageTypes = new Class[]{ |
| HttpServletRequest.class, |
| HttpServletResponse.class |
| }; |
| |
| private MessagePolicy requestPolicy; |
| private MessagePolicy responsePolicy; |
| private CallbackHandler handler; |
| private Map options; |
| private String realmName = null; |
| private String defaultGroup[] = null; |
| privte static final String REALM_PROPERTY_NAME = |
| "realm.name"; |
| private static final String GROUP_PROPERTY_NAME = |
| "group.name"; |
| private static final String BASIC = "Basic"; |
| static final String AUTHORIZATION_HEADER = |
| "authorization"; |
| static final String AUTHENTICATION_HEADER = |
| "WWW-Authenticate"; |
| |
| public void initialize(MessagePolicy reqPolicy, |
| MessagePolicy resPolicy, |
| CallbackHandler cBH, Map opts) |
| throws AuthException { |
| requestPolicy = reqPolicy; |
| responsePolicy = resPolicy; |
| handler = cBH; |
| options = opts; |
| if (options != null) { |
| realmName = (String) |
| options.get(REALM_PROPERTY_NAME); |
| if (options.containsKey(GROUP_PROPERTY_NAME)) { |
| defaultGroup = new String[]{(String) |
| options.get(GROUP_PROPERTY_NAME)}; |
| } |
| } |
| } |
| |
| public Class[] getSupportedMessageTypes() { |
| return supportedMessageTypes; |
| } |
| |
| public AuthStatus validateRequest( |
| MessageInfo msgInfo, Subject client, |
| Subject server) throws AuthException { |
| try { |
| |
| String username = |
| processAuthorizationToken(msgInfo, client); |
| if (username == |
| null && requestPolicy.isMandatory()) { |
| return sendAuthenticateChallenge(msgInfo); |
| } |
| |
| setAuthenticationResult( |
| username, client, msgInfo); |
| return AuthStatus.SUCCESS; |
| |
| } catch (Exception e) { |
| AuthException ae = new AuthException(); |
| ae.initCause(e); |
| throw ae; |
| } |
| } |
| |
| private String processAuthorizationToken( |
| MessageInfo msgInfo, Subject s) |
| throws AuthException { |
| |
| HttpServletRequest request = |
| (HttpServletRequest) |
| msgInfo.getRequestMessage(); |
| |
| String token = |
| request.getHeader(AUTHORIZATION_HEADER); |
| |
| if (token != null && token.startsWith(BASIC + " ")) { |
| |
| token = token.substring(6).trim(); |
| |
| // Decode and parse the authorization token |
| String decoded = |
| new String(Base64.decode(token.getBytes())); |
| |
| int colon = decoded.indexOf(':'); |
| if (colon <= 0 || colon == decoded.length() - 1) { |
| return (null); |
| } |
| |
| String username = decoded.substring(0, colon); |
| |
| // use the callback to ask the container to |
| // validate the password |
| PasswordValidationCallback pVC = |
| new PasswordValidationCallback(s, username, |
| decoded.substring(colon + 1).toCharArray()); |
| try { |
| handler.handle(new Callback[]{pVC}); |
| pVC.clearPassword(); |
| } catch (Exception e) { |
| AuthException ae = new AuthException(); |
| ae.initCause(e); |
| throw ae; |
| } |
| |
| if (pVC.getResult()) { |
| return username; |
| } |
| } |
| return null; |
| } |
| |
| private AuthStatus sendAuthenticateChallenge( |
| MessageInfo msgInfo) { |
| |
| String realm = realmName; |
| // if the realm property is set use it, |
| // otherwise use the name of the server |
| // as the realm name. |
| if (realm == null) { |
| |
| HttpServletRequest request = |
| (HttpServletRequest) |
| msgInfo.getRequestMessage(); |
| |
| realm = request.getServerName(); |
| } |
| |
| HttpServletResponse response = |
| (HttpServletResponse) |
| msgInfo.getResponseMessage(); |
| |
| String header = BASIC + " realm=\"" + realm + "\""; |
| response.setHeader(AUTHENTICATION_HEADER, header); |
| response.setStatus( |
| HttpServletResponse.SC_UNAUTHORIZED); |
| return AuthStatus.SEND_CONTINUE; |
| } |
| |
| public AuthStatus secureResponse( |
| MessageInfo msgInfo, Subject service) |
| throws AuthException { |
| return AuthStatus.SEND_SUCCESS; |
| } |
| |
| public void cleanSubject(MessageInfo msgInfo, |
| Subject subject) |
| throws AuthException { |
| if (subject != null) { |
| subject.getPrincipals().clear(); |
| } |
| } |
| |
| private static final String AUTH_TYPE_INFO_KEY = |
| "javax.servlet.http.authType"; |
| |
| // distinguish the caller principal |
| // and assign default groups |
| private void setAuthenticationResult(String name, |
| Subject s, MessageInfo m) |
| throws IOException, |
| UnsupportedCallbackException { |
| handler.handle(new Callback[]{ |
| new CallerPrincipalCallback(s, name) |
| }); |
| if (name != null) { |
| // add the default group if the property is set |
| if (defaultGroup != null) { |
| handler.handle(new Callback[]{ |
| new GroupPrincipalCallback(s, defaultGroup) |
| }); |
| } |
| m.getMap().put(AUTH_TYPE_INFO_KEY, ""MySAM"); |
| } |
| } |
| } |
| ---- |
| |
| Note that the `initialize` method looks for the `group.name` and |
| `realm.name` properties. The `group.name` property configures the |
| default group assigned as a result of any successful authentication. The |
| `realm.name` property defines the realm value sent back to the browser |
| in the `WWW-Authenticate` challenge. |
| |
| [[gizfa]][[GSDVG00384]][[compiling-and-installing-a-server-authentication-module]] |
| |
| ==== Compiling and Installing a Server Authentication Module |
| |
| Before you can use the sample SAM, you need to compile, install, and |
| configure it. Then you can bind it to an application. |
| |
| To compile the SAM, include the SPI in your classpath. When the |
| {productName} is installed, the JAR file containing the SPI, |
| `jmac-api.jar`, is installed in the as-install``/lib`` directory. After |
| you compile the SAM, install it by copying a JAR file containing the |
| compiled SAM to the as-install``/lib`` directory. |
| |
| [[gizfe]][[GSDVG00385]][[configuring-a-server-authentication-module]] |
| |
| ==== Configuring a Server Authentication Module |
| |
| You can configure a SAM in one of these ways: |
| |
| * In the Administration Console, open the Security component under the |
| relevant configuration and go to the Message Security page. Set the |
| following options: |
| |
| ** Authentication Layer — `HttpServlet` |
| |
| ** Provider Type — `server` or `client-server` |
| |
| ** Provider ID — Specify a unique name for the SAM, for example `MySAM` |
| |
| ** Class Name — Specify the fully qualified class name, for example |
| `tip.sam.MySam` |
| |
| ** Additional Property — Name: `group-name` Value: `user` |
| |
| ** Additional Property — Name: `realm-name` Value: `Sam` |
| + |
| For details, click the Help button in the Administration Console. |
| * Use the `asadmin create-message-security-provider` command to |
| configure a SAM. Set the following options: |
| |
| ** `--layer HttpServlet` |
| |
| ** `--providertype server` or `--providertype client-server` |
| |
| ** `--classname tip.sam.MySam` |
| |
| ** `--property group-name=user:realm-name=Sam` |
| |
| ** Provider name operand — Specify a unique name for the SAM, for |
| example `MySAM` |
| + |
| For details, see the link:reference-manual.html#GSRFM[{productName} |
| Reference Manual]. |
| |
| [[gizfm]][[GSDVG00386]][[binding-a-server-authentication-module-to-your-application]] |
| |
| ==== Binding a Server Authentication Module to Your Application |
| |
| After you install and configure the SAM, you can bind it for use by the |
| container on behalf of one or more of your applications. You have two |
| options in how you bind the SAM, depending on whether you are willing to |
| repackage and redeploy your application: |
| |
| * If you are willing to repackage and redeploy, you can bind the SAM |
| using the `glassfish-web.xml` file. Set the value of the |
| `httpservlet-security-provider` attribute of the `glassfish-web-app` |
| element to the SAM's configured provider ID, for example, `MySAM`. For |
| more information about the `glassfish-web.xml` file, see the |
| link:application-deployment-guide.html#GSDPG[{productName} Application Deployment |
| Guide]. This option leverages the native `AuthConfigProvider` |
| implementation that ships with the {productName}. |
| * Another approach is to develop your own `AuthConfigProvider` and |
| register it with the {productName} `AuthConfigFactory` for use on |
| behalf of your applications. For example, a simple `AuthConfigProvider` |
| can obtain, through its initialization properties, the classname of a |
| SAM to configure on behalf of the applications for which the provider is |
| registered. You can find a description of the functionality of an |
| `AuthConfigProvider` and of the registration facilities provided by an |
| `AuthConfigFactory` in the JSR 196 specification. |
| |
| |