I am trying to implement authentication and authorization for webservice using WS-Security UsernameToken .
Camel version 2.17
Jboss fuse 6.3
Jboss RAP 6.4.17
I have stored my username, password, and role in application realm of the JBoss EAP server.
Iam getting nullpointer in org.apache.wss4j.common.cache.EHCacheManagerHolder
am i missing anything in configuration?
Project location in GIT:
https://github.com/ravi21588/SO/tree/master/authenticationpoc
Soap Request with ws-secutiry headers :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exam="http://Example.org">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>Harish</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">5p[#rnZc!mB[)]8{</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<exam:Add>
<!--Optional:-->
<exam:a>10</exam:a>
<!--Optional:-->
<exam:b>11</exam:b>
</exam:Add>
</soapenv:Body>
</soapenv:Envelope>
Server.log :
18:15:30,688 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http-127.0.0.1:8443-1) Interceptor for {http://Example.org}CalculatorService#{http://Example.org}Add has thrown exception, unwinding now: java.lang.NullPointerException
at org.apache.wss4j.common.cache.EHCacheManagerHolder.getCacheManager(EHCacheManagerHolder.java:106)
at org.apache.cxf.ws.security.cache.EHCacheUtils.getCacheManager(EHCacheUtils.java:49) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.cache.CXFEHCacheReplayCache.<init>(CXFEHCacheReplayCache.java:37) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JUtils.getReplayCache(WSS4JUtils.java:126) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.getReplayCache(WSS4JInInterceptor.java:637) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.configureReplayCaches(WSS4JInInterceptor.java:404) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:237) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:171) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:80) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.17.Final-redhat-4.jar:7.5.17.Final-redhat-4]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]
Server logs after vadim suggetion implementation:
10:01:40,322 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http-127.0.0.1:8080-4) Interceptor for {http://Example.org}CalculatorService#{http://Example.org}Add has thrown exception, unwinding now: org.apache.cxf.interceptor.security.AuthenticationException: Authentication failed (details can be found in server log)
at org.apache.cxf.interceptor.security.JAASLoginInterceptor.handleMessage(JAASLoginInterceptor.java:171) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.17.Final-redhat-4.jar:7.5.17.Final-redhat-4]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]
To do that you can use your own extension from org.apache.cxf.interceptor.security.JAASLoginInterceptor
In general it is very simple. You need to provide to JAASLoginInterceptor an instance of org.apache.cxf.interceptor.security.NamePasswordCallbackHandler.
You have to do 3 steps:
Step1: Interceptor:
package com.foo.security;
import javax.security.auth.callback.CallbackHandler;
import org.apache.cxf.interceptor.security.JAASLoginInterceptor;
import org.apache.cxf.interceptor.security.NamePasswordCallbackHandler;
public class CustomJAASLoginInterceptor extends JAASLoginInterceptor {
#Override
protected CallbackHandler getCallbackHandler(String name, String password) {
return new NamePasswordCallbackHandler(name, password, "setCredential");
}
}
Step2: Then in Camel-Cxf endpoint (or in CXF bus for it) define that interceptor:
<cxf-core:inInterceptors xmlns:cxf-core="http://cxf.apache.org/core">
<spring:bean id="authenticationInterceptor"
class="com.foo.security.CustomJAASLoginInterceptor">
</spring:bean>
</cxf-core:inInterceptors>
Step3: Again in the same Camel-Cxf endpoint (or in CXF bus for it) delegate message authentication out of WSS4J to JAASLoginInterceptor:
<cxf-core:properties>
<!-- delegate message authentication out of WSS4J to JAASLoginInterceptor -->
<spring:entry key="ws-security.validate.token" value="false" />
<!-- ... other properties -->
<cxf-core:properties>
After all it works seamlessly with JBoss EAP JAAS for users defined in EAP Application realm.
UPDATE 1:
It looks like you have to define in standalone.xml (or domain.xml) additional security domain and Login module for ApplicationRealm. I'm not sure which one is responsible for WebServices so, what I have in my standalone.xml
<subsystem xmlns="urn:jboss:domain:security:1.2">
...
<security-domain name="jboss-web-policy" cache-type="default">
<authentication>
<login-module code="RealmDirect" flag="optional">
<module-option name="realm" value="ApplicationRealm"/>
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="RealmDirect" flag="optional">
<module-option name="realm" value="ApplicationRealm"/>
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
<authorization>
<policy-module code="Web" flag="sufficient"/>
<policy-module code="Delegating" flag="sufficient"/>
</authorization>
</security-domain>
I do not see more differences in my working standalone.xml vs. default one provided with EAP installation.
UPDATE 2
So working WSSE header (built by SoapUI) looks like:
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-45417D5A3EF19629C315173319098351">
<wsse:Username>my_username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">my_password</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">qY0N9DfYcd7kQfBkfNilRw==</wsse:Nonce>
<wsu:Created>2018-01-30T17:05:09.835Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
P.S. It also works with no nonce nor timestamp, but it is better to use them.
Related
I'm using Wildfly 10 and I'm trying to add an expression filter in the undertow configuration to validate the secret value from mod_jk. It is however always returning error code 403.
Below is my configuration in standalone-full.xml
<subsystem xmlns="urn:jboss:domain:undertow:7.0" ...>
...
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<ajp-listener name="ajp" socket-binding="ajp"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
...
<!-- add the following with your AJP port (8009) -->
<filter-ref name="secret-checker" predicate="equals(%p, 8009)"/>
</host>
</server>
...
<filters>
<!-- add the following with your credential (YOUR_AJP_SECRET) -->
<expression-filter name="secret-checker" expression="not equals(%{r,secret}, 'verysecure') -> response-code(403)"/>
</filters>
Below is the configuration in workers.properties for mod_jk.
worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=127.0.0.1
worker.ajp13.type=ajp13
worker.ajp13.secret=verysecure
I'm trying to mitigate the ghostcat vulnerability detailed on this link.
https://access.redhat.com/solutions/4851251
Any help is appreciated. Thanks in advance.
place "and equals(%{PROTOCOL}, 'AJP')" after the port.
predicate="equals(%p, 8009) and equals(%{PROTOCOL}, 'AJP')"
but I am getting a 404 and not the expected 403 :(
I am trying to implement authentication and authorization using WS-Security UsernameToken in my CXF inbound endpoint using SubjectCreatingInterceptor.
I have stored my username, password, and role information in application properties of the JBoss EAP server.
Bean configuration is as below.
endpoints.xml:
<bean id="authenticationInterceptor" class="org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken"/>
</map>
</constructor-arg>
</bean>
<bean id="authorizationInterceptor" class="org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor">
<property name="globalRoles" value="testrole"/>
</bean>
<cxf:cxfEndpoint id="auth-endpoint"
xmlns:nms="http://tempuri.org/"
address="http://localhost:9090/auth/test"
endpointName="nms:BasicHttpBinding_IRmsAuthenticationService"
serviceName="nms:RmsAuthenticationService"
wsdlURL="wsdl/Authentication_1.wsdl"
loggingFeatureEnabled="true">
<cxf:properties>
<entry key="ws-security.validate.token" value="false" />
<entry key="dataFormat" value="MESSAGE"/>
</cxf:properties>
<cxf:inInterceptors>
<ref bean="authenticationInterceptor" />
<ref bean="authorizationInterceptor" />
</cxf:inInterceptors>
</cxf:cxfEndpoint>
Soap request XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:upm="http://testservices.com">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>testauth</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">testauth#123</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<upm:GetToken2>
<upm:Token>test</upm:Token>
</upm:GetToken2>
</soapenv:Body>
After triggering the request it is giving the below error:
WARN org.apache.cxf.phase.PhaseInterceptorChain Interceptor for {
http://tempuri.org/}RmsAuthenticationService has thrown exception, unwinding now: java.lang.NullPointerException
at org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor.handleMessage(SubjectCreatingInterceptor.java:95) [jbossws-cxf-server-4.3.6.Final-redhat-1.jar:4.3.6.Final-redhat-1]
at org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingInterceptor.handleMessage(SubjectCreatingInterceptor.java:61) [jbossws-cxf-server-4.3.6.Final-redhat-1.jar:4.3.6.Final-redhat-1]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234) [cxf-rt-transports-http-jetty-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70) [cxf-rt-transports-http-jetty-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151-1-redhat]
Could you please suggest what is missing. Thanks in advance.
Dear Ricardo, We have tried implementing WSS4J interceptor as you suggested. But we are facing the below issue, WARN [org.eclipse.jetty.server.HttpChannel] (qtp1703888095-358) /auth/test: java.lang.NoSuchFieldError: SAML_TOKEN
at org.apache.cxf.ws.security.wss4j.CXFRequestData.(CXFRequestData.java:39) [cxf-rt-ws-security-3.1.12.jar:3.1.12]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:184) [cxf-rt-ws-security-3.1.12.jar:3.1.12]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:171) [cxf-rt-ws-security-3.1.12.jar:3.1.12]
at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:80) [cxf-rt-ws-security-3.1.12.jar:3.1.12]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234) [cxf-rt-transports-http-jetty-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70) [cxf-rt-transports-http-jetty-3.1.5.redhat-630262.jar:3.1.5.redhat-630262]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.19.v20160908.jar:9.2.19.v20160908]
at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151-1-redhat]
It looks like its not able to initialize the CXFrequestdata java class. We have used util
<util:constant
static-field="org.apache.wss4j.dom.handler.WSHandlerConstants.ACTION"/>
within the constructor-arg while declaring the WSS4JInterceptor bean in order avoid the constants loading in CXFRequestData class. Could you please suggest how we can proceed further. Thank you.!!
Currently I have configured my application with Kerberos authentication for a specific user's in jboss-eap by specifying users name in standalone.xml and it's working fine. But wants to configure the same on the basis of the ldap i.e users in a AD will able to authenticate directly and i need not to specify the username in standalone.xml.
Standalone.xml working fine:- Specifying the username in stanadalone.xml
<security-domains>
<security-domain name="SPNEGO" cache-type="default">
<authentication>
<login-module code="SPNEGO" flag="required">
<module-option name="serverSecurityDomain" value="host"/>
</login-module>
</authentication>
<mapping>
<mapping-module code="SimpleRoles" type="role">
<module-option name="saurabhgupta#ECO.COM" value="User"/>
</mapping-module>
</mapping>
</security-domain>
<security-domain name="host" cache-type="default">
<authentication>
<login-module code="Kerberos" flag="required">
<module-option name="debug" value="true"/>
<module-option name="storeKey" value="true"/>
<module-option name="refreshKrb5Config" value="true"/>
<module-option name="useKeyTab" value="true"/>
<module-option name="doNotPrompt" value="true"/>
<module-option name="keyTab" value="/spengo/jboss-eap-6.2/bin/krb.keytab"/>
<module-option name="principal" value="HTTP/vm428.eco.com#ECO.COM"/>
</login-module>
</authentication>
Standalone.xml:- To configure ldap
<security-domains>
<security-domain name="SPNEGO" cache-type="default">
<authentication>
<login-module code="SPNEGO" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="serverSecurityDomain" value="host"/>
</login-module>
<login-module code="LdapExtended" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="java.naming.provider.url" value="ldap://AD IP:389"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="bindDN" value="CN=siddharth,CN=Users,DC=eco,DC=com"/>
<module-option name="bindCredential" value="password"/>
<module-option name="baseCtxDN" value="CN=Users,DC=eco,DC=com"/>
<module-option name="baseFilter" value="(uid={0})"/>
<module-option name="searchScope" value="ONELEVEL_SCOPE"/>
<module-option name="allowEmptyPasswords" value="true"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="host" cache-type="default">
<authentication>
<login-module code="Kerberos" flag="required">
<module-option name="debug" value="true"/>
<module-option name="storeKey" value="true"/>
<module-option name="refreshKrb5Config" value="true"/>
<module-option name="useKeyTab" value="true"/>
<module-option name="doNotPrompt" value="true"/>
<module-option name="keyTab" value="/spengo/jboss-eap-6.2/bin/krb.keytab"/>
<module-option name="principal" value="HTTP/vm428.eco.com#ECO.COM"/>
</login-module>
</authentication>
</security-domain>
My environment consists of:- linux server with JBoss EAP 6.2 client station with Windows 7 64bit + Chrome Windows Server 2008 Active Directory (act as KDC)
But facing an error of 401 in browser window.
**Error:-** JBWEB000065: HTTP Status 401 -
--------------------------------------------------------------------------------
JBWEB000309: type JBWEB000067: Status report
JBWEB000068: message
JBWEB000069: description JBWEB000121: This request requires HTTP authentication.
--------------------------------------------------------------------------------
JBoss Web/7.2.2.Final-redhat-1
Did anyone have this problem and solve it somehow?
I migrate a project from Java EE 6 to Java EE 7.
As dependencies I have javaee 7.0, payara-embedded-all4.1.1.154
I migrate beans.xml to:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<interceptors>
<class>com.myproject.business.base.util.LoggingInterceptor</class>
</interceptors>
</beans>
Also the web.xml to:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>com.myproject.business.server</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>myprojectRealm</realm-name>
</login-config>
<security-constraint>
<display-name>Basic Protection</display-name>
<web-resource-collection>
<web-resource-name>REST</web-resource-name>
<description />
<url-pattern>/myproject/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description />
<role-name>com.myproject.ftc.Reader</role-name>
<role-name>com.myproject.um.Administrator</role-name>
<role-name>com.myproject.ftc.Skriptimporteur</role-name>
<role-name>com.myproject.operations.Admin</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>com.myproject.ftc.Reader</role-name>
</security-role>
<security-role>
<role-name>com.myproject.ftc.Exporter</role-name>
</security-role>
<security-role>
<role-name>com.myproject.operations.Admin</role-name>
</security-role>
</web-app>
And is replaced sun-web.xml with glassfish-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<context-root>/com.myproject.business.server</context-root>
</glassfish-web-app>
Everything is compilable but I have a problem when I want to deploy the app to payara:
2016-03-09T17:16:19.466+0200|Severe: Exception during lifecycle processing
java.lang.RuntimeException: EJB Container initialization error
at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:237)
at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:291)
at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:99)
at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:206)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:314)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:487)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.myproject.exception.handler.__EJB31_Generated__ExceptionDelegate__Intf____Bean__.registerExceptionHandler(Unknown Source)
at com.myproject.exception.handler.ExceptionDelegate.init(ExceptionDelegate.java:40)
at com.myproject.exception.handler.ExceptionDelegate.<init>(ExceptionDelegate.java:31)
at com.myproject.exception.handler.__EJB31_Generated__ExceptionDelegate__Intf____Bean__.<init>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3867)
at com.sun.ejb.containers.AbstractSingletonContainer.initializeHome(AbstractSingletonContainer.java:216)
at com.sun.ejb.containers.SingletonContainerFactory.createContainer(SingletonContainerFactory.java:72)
at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:225)
... 43 more
What is also strange is that it gives me EJB31_Generated and I added a maven-ejb-plugin with version 3.2 and have Payara 4.1.1.154.
Anyone has any idea why?
I solved it. Was about to register some resources:
#ApplicationPath("project")
public class RESTConfig extends Application {
#Override public Set<Class<?>> getClasses() {
final Set<Class<?>> resources = new HashSet<Class<?>>(); // Add your resources.
resources.add(AdminConsoleResource.class); // Add additional features such as support for Multipart.
resources.add(MultiPartFeature.class);
return resources;
}
}
I'm new to ADF mobile application development. I'm currently blocked in a scenario. I have a web service(from third party) which needs to retrieve data. In soapUI, the web service will retrieve the response only when there is this security tag. Otherwise it will give response as invalid security. The web service looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xx="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/" xmlns:get="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/get_login/">
<soapenv:Header>
<xx:SOAHeader>
<!--Optional:-->
<xx:Responsibility>XXX</xx:Responsibility>
<!--Optional:-->
<xx:RespApplication>XXX</xx:RespApplication>
<!--Optional:-->
<xx:SecurityGroup>XXX</xx:SecurityGroup>
<!--Optional:-->
<xx:NLSLanguage>XXX</xx:NLSLanguage>
<!--Optional:-->
<xx:Org_Id>XXX</xx:Org_Id>
</xx:SOAHeader>
<The portion which is excluded from the soap, but which is required for getting response>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1">
<wsse:Username>XXX</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXX</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">XXX</wsse:Nonce>
<wsu:Created>2013-02-13T08:58:50.649Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<The portion which is excluded from the soap, but which is required for getting response>
</soapenv:Header>
<soapenv:Body>
<get:InputParameters>
<!--Optional:-->
<get:P_USERNAME>XXX</get:P_USERNAME>
</get:InputParameters>
</soapenv:Body>
</soapenv:Envelope>
I tried the steps described in ADF mobile tutorial to get web service data. But I'm getting response code 500 from the server. I tried the steps for secured web service also. But I'm not sure which security policy has been implemented in the web service. I tried with oracle/wss_username_client_token_policy and some others but didn't succeed. Later I tried by creating web service client/proxy. But as Oracle ADF only supports java 1.4, I got errors in the generated code(errors on generics and annotation).
The WSDL for the web service is as follows:
<definitions xmlns:tns="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns1="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/get_login/" name="XX_FS_MOB_LOGIN" targetNamespace="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/get_login/">
<include schemaLocation="http://27.251.157.211:8000/webservices/SOAProvider/plsql/xx_fs_mob_login/APPS_XX_FS_MOB_LOGIN_GET_LOGIN.xsd"/>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/apps/csf/soaprovider/plsql/xx_fs_mob_login/">
<element name="SOAHeader">
<complexType>
<sequence>
<element name="Responsibility" minOccurs="0" type="string"/>
<element name="RespApplication" minOccurs="0" type="string"/>
<element name="SecurityGroup" minOccurs="0" type="string"/>
<element name="NLSLanguage" minOccurs="0" type="string"/>
<element name="Org_Id" minOccurs="0" type="string"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="GET_LOGIN_Input_Msg">
<part name="header" element="tns:SOAHeader"/>
<part name="body" element="tns1:InputParameters"/>
</message>
<message name="GET_LOGIN_Output_Msg">
<part name="body" element="tns1:OutputParameters"/>
</message>
<portType name="XX_FS_MOB_LOGIN_PortType">
<operation name="GET_LOGIN">
<input message="tns:GET_LOGIN_Input_Msg"/>
<output message="tns:GET_LOGIN_Output_Msg"/>
</operation>
</portType>
<binding name="XX_FS_MOB_LOGIN_Binding" type="tns:XX_FS_MOB_LOGIN_PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GET_LOGIN">
<soap:operation soapAction="http://XXX:8000/webservices/SOAProvider/plsql/xx_fs_mob_login/"/>
<input>
<soap:header message="tns:GET_LOGIN_Input_Msg" part="header" use="literal"/>
<soap:body parts="body" use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="XX_FS_MOB_LOGIN_Service">
<port name="XX_FS_MOB_LOGIN_Port" binding="tns:XX_FS_MOB_LOGIN_Binding">
<soap:address location="http://XXX:8000/webservices/SOAProvider/plsql/xx_fs_mob_login/"/>
</port>
</service>
</definitions>
Please help me to figure out a solution for this.
Thanks in advance
Rino
You won't be able to get far in accessing a secure Web service directly from ADF Mobile if you don't know the type of security it uses.
If you can create a proxy client that invokes the web service, then one solution is to run that on the server, and expose that client as a web service that the ADF Mobile layer can access.