users@glassfish.java.net

Re: JAAS HTTP Status 403 - Access to the requested resource has been denied

From: Nithya Subramanian <Nithya.Subramanian_at_Sun.COM>
Date: Thu, 22 Jan 2009 15:41:50 +0530

Daniel H. Cavalcanti wrote:
> Yeap,
>
> Cloning the groups array worked. The link that you sent has the
>
> Question: The link that you sent has the commitUserAuthentication
> method with a different signature:
> commitUserAuthentication(_username, _password, _currentRealm, grpList);
>
> The current implementation just taked the grpList parameter.
> Is the current signature going to be deprecated? Why the shift (just
> curious on the reason to pass the extra args).
The right signature is commitUserAuthentication(String[] groupList). The
4 arg signature in the doc is being corrected.
>
> Also, I've google this and got a lot of people with the same question
> and but a definite answer. Why does the custom login module have to
> extend the AppservPasswordLoginModule class. This makes the custom
> LoginModule not portable. Same thing with the custom Realm class that
> needs to extend AppservRealm.
>
> Why can the custom realm and login module just extend Realm and
> LoginModule directly?
The AppservPasswordLoginModule layer (that implements JAAS LoginModule)
provides the implementations of methods like initialize( where the
configuration parameters are read and set) ,login(), commit() and
logout(clearing the principals) and helps the application developer to
concentrate on just the login process using the authenticateUser()
method, alleviating the need to implement the others.

Thanks
Nithya
>
> Although we're targeting GlassFish as our application server platform,
> we'd like to be independent of it in case a customer wishes to deploy
> into another JEE 5 compliant AS.
>
> thanks,
> Daniel.
>
> Nithya Subramanian wrote:
>> This is an expected scenario, please refer to the Note regarding this
>> in this link: http://docs.sun.com/app/docs/doc/820-4496/beabs?a=view
>>
>> Since the member variable - groupname array is set to null after
>> authentication succeeds, 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 variable.
>>
>> Hope this helps and if it is easier than analyzing the JDBCRealm
>> feasibility discussion.
>>
>> Thanks
>> Nithya
>>
>> Daniel H. Cavalcanti wrote:
>>> Hi,
>>>
>>> We have an application that uses a database whose schema doesn't fit
>>> the
>>> JDBCRealm schema. So to use JAAS we had to implement our own
>>> LoginModule
>>> and Realm classes:
>>>
>>> public class AccessManagerLoginModule
>>> extends AppservPasswordLoginModule{
>>>
>>> @Override
>>> protected void authenticateUser()
>>> throws LoginException {
>>>
>>> try {
>>>
>>> if (!(_currentRealm instanceof AccessManagerRealm))
>>> throw new LoginException("Bad realm: " +
>>> _currentRealm);
>>>
>>> AccessManagerRealm realm = (AccessManagerRealm)
>>> _currentRealm;
>>> String[] groups = realm.authenticateUser(_username,
>>> _password);
>>>
>>> commitUserAuthentication(groups);
>>>
>>> } catch (LoginException ex) {
>>> log.error("Login failed", ex);
>>> throw ex;
>>> } catch (Throwable ex) {
>>> log.error("Unexpected error.", ex);
>>> throw new LoginException("Unexpected error.");
>>> }
>>>
>>> }
>>>
>>> }
>>>
>>> and
>>>
>>> public class AccessManagerRealm
>>> extends AppservRealm {
>>>
>>> public static final String AUTH_TYPE = "FlexiQ AccessManager
>>> Custom
>>> Realm";
>>>
>>> public static final String[] GROUPS = new String[]
>>> {"administrator", "supervisor", "operator", "guest"};
>>>
>>> public static final String USERNAME = "dhcavalcanti";
>>> public static final String PASSWORD = "123456";
>>>
>>> private Log log = LogFactory.getLog(getClass());
>>>
>>> protected void init(Properties props)
>>> throws BadRealmException, NoSuchRealmException {
>>> super.init(props);
>>> }
>>>
>>> @Override
>>> public String getAuthType() {
>>> return AUTH_TYPE;
>>> }
>>>
>>> @Override
>>> public Enumeration getGroupNames(String username)
>>> throws InvalidOperationException, NoSuchUserException {
>>> List<String> groups = new ArrayList<String>(GROUPS.length);
>>> for (String group : GROUPS)
>>> groups.add(group);
>>> System.out.println("groups: " + groups);
>>> return Collections.enumeration(groups);
>>> }
>>>
>>> public String[] authenticateUser(String username, String password)
>>> throws LoginException, PersistenceException {
>>>
>>> if (log.isTraceEnabled())
>>> log.trace("Authenticating user: " + username + " [" +
>>> password + "]");
>>>
>>> if (!USERNAME.equals(username))
>>> throw new LoginException("User not found: " + username);
>>> if (!PASSWORD.equals(password))
>>> throw new LoginException("Invalid password");
>>>
>>> return GROUPS;
>>>
>>> }
>>>
>>> }
>>>
>>> So far we hard coded the username and password to test this custom
>>> classes.
>>>
>>> In the web.xml we added
>>>
>>> <security-constraint>
>>> <display-name>FlexiQ AccessManager Security -
>>> Login</display-name>
>>> <web-resource-collection>
>>> <web-resource-name>FlexiQ AccessManager protected
>>> area.</web-resource-name>
>>> <url-pattern>/authenticated/*</url-pattern>
>>> <http-method>GET</http-method>
>>> <http-method>POST</http-method>
>>> <http-method>HEAD</http-method>
>>> <http-method>PUT</http-method>
>>> <http-method>OPTIONS</http-method>
>>> <http-method>TRACE</http-method>
>>> <http-method>DELETE</http-method>
>>> </web-resource-collection>
>>> <auth-constraint>
>>> <role-name>administrator</role-name>
>>> <role-name>supervisor</role-name>
>>> <role-name>operator</role-name>
>>> <role-name>guest</role-name>
>>> </auth-constraint>
>>> <user-data-constraint>
>>> <transport-guarantee>CONFIDENTIAL</transport-guarantee>
>>> </user-data-constraint>
>>> </security-constraint>
>>>
>>> <security-role>
>>> <role-name>administrator</role-name>
>>> </security-role>
>>> <security-role>
>>> <role-name>supervisor</role-name>
>>> </security-role>
>>> <security-role>
>>> <role-name>operator</role-name>
>>> </security-role>
>>> <security-role>
>>> <role-name>guest</role-name>
>>> </security-role>
>>>
>>> <login-config>
>>> <auth-method>BASIC</auth-method>
>>> <realm-name>access-manager</realm-name>
>>> </login-config>
>>>
>>> and in the sun-web.xml we added
>>>
>>> <security-role-mapping>
>>> <role-name>administrator</role-name>
>>> <group-name>administrator</group-name>
>>> </security-role-mapping>
>>> <security-role-mapping>
>>> <role-name>supervisor</role-name>
>>> <group-name>supervisor</group-name>
>>> </security-role-mapping>
>>> <security-role-mapping>
>>> <role-name>operator</role-name>
>>> <group-name>operator</group-name>
>>> </security-role-mapping>
>>> <security-role-mapping>
>>> <role-name>guest</role-name>
>>> <group-name>guest</group-name>
>>> </security-role-mapping>
>>>
>>> In <domain>/config/login.conf we added
>>>
>>> accessManagerRealm {
>>>
>>> com.localmatters.flexiq.accessmanager.jaas.AccessManagerLoginModule
>>> required;
>>> };
>>>
>>> Etc.
>>>
>>> When we test the web application, we expectedly get the credentials
>>> prompt, enter the username/password and successfully get the page we
>>> requested. However, if we refresh the browser, we simply get the HTTP
>>> 403 error code.
>>>
>>> We don't know what's going on here. I removed most of the logging code
>>> from the classes to make it clean, but we have logging for the username
>>> and password, and even when we refresh the page, we see the correct
>>> username/password.
>>>
>>> For example, when we get the prompt and enter the right
>>> username/password, the log shows:
>>>
>>> deployed with moduleid = access-manager-web
>>> Initializing Sun's JavaServer Faces implementation (1.2_04-b20-p03) for
>>> context '/access-manager'
>>> Initializing Sun's JavaServer Faces implementation (1.2_04-b20-p03) for
>>> context ''
>>> JACC Policy Provider: PolicyWrapper.implies,
>>> context(access-manager-web/access-manager-web)-
>>> permission((javax.security.jacc.WebUserDataPermission
>>> /authenticated/home.faces GET)) domain that failed(ProtectionDomain
>>> (file:/access-manager-web/access-manager-web <no signer certificates>)
>>> null
>>> <no principals>
>>> java.security.Permissions_at_d2c05d (
>>> (javax.management.MBeanPermission [com.sun.messaging.jms.*:*] *)
>>> (javax.management.MBeanTrustPermission register)
>>> (unresolved javax.security.jacc.WebUserDataPermission
>>> /:/authenticated/* null)
>>> (unresolved javax.security.jacc.WebUserDataPermission
>>> /authenticated/*
>>> !DELETE,GET,HEAD,OPTIONS,POST,PUT,TRACE)
>>> (unresolved javax.security.jacc.WebUserDataPermission
>>> /authenticated/*
>>> DELETE,GET,HEAD,OPTIONS,POST,PUT,TRACE:CONFIDENTIAL)
>>> (unresolved
>>> com.sun.corba.ee.impl.presentation.rmi.DynamicAccessPermission
>>> access null)
>>> (unresolved javax.security.jacc.WebResourcePermission
>>> /authenticated/*
>>> !DELETE,GET,HEAD,OPTIONS,POST,PUT,TRACE)
>>> (unresolved javax.security.jacc.WebResourcePermission
>>> /:/authenticated/* null)
>>> (unresolved com.sun.enterprise.security.CORBAObjectPermission * *)
>>> (java.net.SocketPermission localhost:1024- listen,resolve)
>>> (java.net.SocketPermission * connect,resolve)
>>> (java.lang.RuntimePermission getClassLoader)
>>> (java.lang.RuntimePermission loadLibrary.*)
>>> (java.lang.RuntimePermission accessDeclaredMembers)
>>> (java.lang.RuntimePermission getProtectionDomain)
>>> (java.lang.RuntimePermission modifyThreadGroup)
>>> (java.lang.RuntimePermission stopThread)
>>> (java.lang.RuntimePermission setContextClassLoader)
>>> (java.lang.RuntimePermission queuePrintJob)
>>> (javax.security.auth.PrivateCredentialPermission
>>> javax.resource.spi.security.PasswordCredential * "*" read)
>>> (java.io.FilePermission /tmp/- delete)
>>> (java.io.FilePermission
>>> /var/lib/glassfishv2/domains/domain1/lib/databases/- delete)
>>> (java.io.FilePermission <<ALL FILES>> read,write)
>>> (java.util.PropertyPermission line.separator read)
>>> (java.util.PropertyPermission java.vm.version read)
>>> (java.util.PropertyPermission java.vm.specification.version read)
>>> (java.util.PropertyPermission java.vm.specification.vendor read)
>>> (java.util.PropertyPermission java.vendor.url read)
>>> (java.util.PropertyPermission java.vm.name read)
>>> (java.util.PropertyPermission * read,write)
>>> (java.util.PropertyPermission os.name read)
>>> (java.util.PropertyPermission java.vm.vendor read)
>>> (java.util.PropertyPermission path.separator read)
>>> (java.util.PropertyPermission java.specification.name read)
>>> (java.util.PropertyPermission os.version read)
>>> (java.util.PropertyPermission os.arch read)
>>> (java.util.PropertyPermission java.class.version read)
>>> (java.util.PropertyPermission java.version read)
>>> (java.util.PropertyPermission file.separator read)
>>> (java.util.PropertyPermission java.vendor read)
>>> (java.util.PropertyPermission java.vm.specification.name read)
>>> (java.util.PropertyPermission java.specification.version read)
>>> (java.util.PropertyPermission java.specification.vendor read)
>>> )
>>> )
>>> Resolving realm...
>>> Realm resolved: access-manager. Delegating authentication to realm...
>>> Authenticating user: dhcavalcanti [123456]
>>> [TopLink Info]: 2009.01.19
>>> 12:44:00.348--ServerSession(10893564)--TopLink, version: Oracle TopLink
>>> Essentials - 2.0.1 (Build SNAPSHOT (02/01/2008))
>>> [TopLink Info]: 2009.01.19
>>> 12:44:01.519--ServerSession(10893564)--file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-JAAS/dist/access-manager-JAAS.jar-AccessManagerPersistence
>>>
>>> login successful
>>> Committing user authentication: bind user to group membership.
>>> User authenticated.
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/jsf-facelets.jar!/META-INF/jsf-core.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/jsf-facelets.jar!/META-INF/jsf-html.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/jsf-facelets.jar!/META-INF/jsf-ui.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/jsf-facelets.jar!/META-INF/jstl-core.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/jsf-facelets.jar!/META-INF/jstl-fn.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/trinidad-impl-1.2.10.jar!/META-INF/tr.taglib.xml
>>>
>>> Added Library from:
>>> jar:file:/home/dhcavalcanti/projects/FlexiAccessManager/implementation/access-manager-web/build/web/WEB-INF/lib/trinidad-impl-1.2.10.jar!/META-INF/trh.taglib.xml
>>>
>>>
>>> We get the page as expected. Then we refresh the page through the
>>> browser and get the HTTP 403 error page, the log (continued from the
>>> one
>>> above) shows:
>>>
>>> Resolving realm...
>>> Realm resolved: access-manager. Delegating authentication to realm...
>>> Authenticating user: dhcavalcanti [123456]
>>> Committing user authentication: bind user to group membership.
>>> User authenticated.
>>>
>>> Is this a bug, are we doing something wrong?
>>> Any help is greatly appreciated.
>>>
>>> thanks,
>>> Daniel
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
>>> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>