Jboss 5.1.0 EJB Security (unauthenticated principal via JNDI) - security

How do you secure remote EJBs from unauthenticated principal in JBoss-5.1.0.GA application server? After configuring my ejb security I can still access the remote EJBs with a JNDI lookup without principal and credentials passed in? This is a security risk. Essentially I want to disable all unauthenticated JNDI lookup on remote EJBs.
Here is my server/conf/login-config.xml configruation:
<application-policy name="<my security domain name>">
<authentication>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="dsJndiName">**java:jdbc/<my datasource name>**</module-option>
<module-option name="principalsQuery"><my users query></module-option>
<module-option name="rolesQuery"><my roles query></module-option>
<module-option name="debug">true</module-option>
</login-module>
</authentication>
</application-policy>
Here is my jboss.xml configruation in my ejb jar:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC
"-//JBoss//DTD JBOSS 5.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_5_0.dtd">
<jboss>
<security-domain><my security domain name from login-config></security-domain>
</jboss>
Here is how i do a a JNDI lookup to access my beans as a client
Note the principal and credentials are not being passed in to the context
Hashtable<String, String> props = new Hashtable<String, String>();
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
props.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
props.put(Context.PROVIDER_URL,"jnp://localhost:1099");
//props.put(Context.SECURITY_PRINCIPAL,"");
//props.put(Context.SECURITY_CREDENTIALS,"");
ctx = new InitialContext(props);
ctx.lookup("<earname>/<ejb interface definition>/remote">
What is the issue?
When no/wrong principal/credentials are passed the user is authenticated as an anonymous principal and has full access to the remote EJBs via JNDI
What I tried already to fix the issue:
i deleted the following line from all login modules in my server/conf/login-config.xml but it had no effect
<module-option name="unauthenticatedIdentity">anonymous</module-option>
i deleted following line from server/conf/jboss-service.xml thinking it will resolve the issue, but it had no effect
<attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
i deleted application policy "client-login" from login-config.xml that is in there by default since i am using a DatabaseLoginModule
My jboss-ejb-policy and jboss-web-policy in server/depoly/security/security-policies-jboss-beans.xml are extending my DatabaseLoginModule policy in login-config.xml
I have no security related annotations in my ejb classes/interfaces
Other things to note
I tested this scenario in Jboss-as-7.1.1.final and i get EjbAccessException: invalid User which is correct (you add this to the jboss-ejb3.xml it will secure all EJBs via the security domain)
<assembly-descriptor>
<s:security>
<ejb-name>*</ejb-name>
<s:security-domain><security domain name here></s:security-domain>
</s:security>
</assembly-descriptor>
the issue here is NOT authorization but authentications all ejb security annotations do not help
what i want to do is prevent the anonymous principal completely from making JNDI call
I have enabled TRACE logging on org.jboss.security and i can see that when ever i call the JNDI i get the following hit in the logs
Principal: anonymous:callerRunAs=null:callerRunAs=null:ejbRestrictionEnforcement=false:ejbVersion=null]; policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration#1f51a2f;
I have verified all my configurations work and the DatabaseLoginModule works when i use the programmatic login through WebAuthetication
Even when passing the initial context a valid principal/credential from database the anonymous principal is used indicating that the principal/credential is not even processed by the context
I can probably secure my EJBs through #RolesAllowed #DeclareRoles ... but like i mentioned this would be an authorization concern not authentication and also if I have many roles and EJBs this would not be good as far as maintainability
How can I disable/prevent unauthenticated anonymous JNDI lookup for the entire application like it automatically does in JBoss 7.1.1? I know I can upgrade my application server as one solution but I don't have the option to do so. This should be possible and easy to do in Jboss 5.1.0. but i have looked for the answer everywhere and I can't find it? Thanks for your help.

Related

Can I Use SSL and ACL authentication/authorization only for SSL listener (not for PLAINTEXT) in Kafka?

I would like to run a Kafka cluster with 2 listeners. One SSL and one PLAINTEXT listener.
The SSL listener should be secured by authentication/authorization via SSL and ACL. Only known users should be allowed to access it.
On the PLAINTEXT port any user or anonymous user should have full access.
If I set the property
allow.everyone.if.no.acl.found=false
however, anonymous users will no longer be able to access the PLAINTEXT port. Is there any way to configure the system as described above?
I can think of 2 ways to achieve that. Depending on your exact configuration you may prefer one or the other.
ACLs only
Each connection to Kafka is associated with a Principal. Principal can be customized using a custom PrincipalBuilder but the default implementation should build different principals for users connecting over SSL and PLAINTEXT. Via PLAINTEXT, all users should be ANONYMOUS and via SSL they should get names based on these SSL mapping rules.
So you should be able to add an ACL granted everything to Principal User:ANONYMOUS and set specific ACLs for the SSL users.
Custom Authorizer
This is slightly more involved but it should grant you more freedom. You can implement a simple custom Authorizer that makes decisions based on the listener.
If you already have a custom Authorizer, you can retrieve the listener from AuthorizableRequestContext.listenerName() and return allowed if it's the PLAINTEXT listener.
If you are using the default AclAuthorizer that comes with Kafka, you can extend it to check the listener name:
public class AllowPlaintextAuthSslAuthorizer extends AclAuthorizer {
#Override
public List<AuthorizationResult> authorize(AuthorizableRequestContext requestContext, List<Action> actions) {
if ("PLAINTEXT".equals(requestContext.listenerName())) {
return actions.stream()
.map((Action a) -> AuthorizationResult.ALLOWED)
.collect(Collectors.toList());
} else {
return super.authorize(requestContext, actions);
}
}
}
Then in your server.properties file, set authorizer.class.name to use your custom class.
Note that AclAuthorizer is not part of the public API so it may change in the future.

TAI for MS Azure with Websphere Application Server v9 CWWSS8017E: Authentication Error

I'm trying to configure SAML between MS Azure AD and a WebSphere v9 CF11 server that's sitting in AWS. But it is not recognizing the TAI set up
I've followed all the steps here: https://www.ibm.com/support/knowledgecenter/en/SSAW57_9.0.0/com.ibm.websphere.nd.multiplatform.doc/ae/tsec_enable_saml_sp_sso.html and here https://www.ibm.com/support/knowledgecenter/en/SSAW57_9.0.0/com.ibm.websphere.nd.multiplatform.doc/ae/twbs_configuresamlssopartners.html
I've installed the SAMLSA app in WebSphere, imported the metadata file provided by my Azure admin, and imported the certificate as well. I've set up the ACSTrustAssociationInterceptor interceptor and put in (what I thought was) the right sso_1.sp.acsUrl and other settings for the server.
The SystemOut logs show that the ACSTrustAssociationInterceptor is loading:
SECJ0121I: Trust Association Init class com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor loaded successfully
but the version is null:
SECJ0122I: Trust Association Init Interceptor signature:
After setting it all up as above, when I go to the URL it just shows:
Error 403: AuthenticationFailed
And the log has errors about a missing cookie:
SECJ0126E: Trust Association failed during validation. The exception is com.ibm.websphere.security.WebTrustAssociationFailedException: CWWSS8017E: Authentication Error: Single-Sign-on cookie is not present or could not be verified. Please login to the SAML Identity Provider, and try again.
It's like it's never "intercepted" to be passed. Just fails. No network traffic goes to the AD server
When going to the URL it should redirect me to the MS Login and then back to the app, but it's not
It sounds like you might be missing an sso_1.sp.login.error.page property definition. Without that property, the expectation is that the user will be going to the IdP to initiate the sign on; if you define the property and set its value to your IdP's login page, then the 403 you're getting (as a result of being unauthenticated) will end up redirecting you over to the IdP to initiate the sign on process from there.
More info here in the "bookmark style" description: https://www.ibm.com/support/knowledgecenter/en/SSAW57_9.0.0/com.ibm.websphere.nd.multiplatform.doc/ae/cwbs_samlssosummary.html

IBM MobileFirst Adapters security roles

Is it possible to use JAX-RS2 security roles in MF adapters?
E.g.:
securityContext.isUserInRole("MyTestRole")
This method returns always false in my adapter. I added in "mfp" app (mfp-server.war) in server.xml (LibertyProfile):
<security-role name="MyTestRole">
<group name="MyLDAPGroup" />
</security-role>
and I am logged in to user that is assigned to "MyLDAPGroup".
Or maybe in MF adapters we should use some other mechanism to specify roles?
You may want to check the following links:
Implementing a JAX-RS resource & security configuration of a JAX-RS resource in MFP v8.0:
https://www.ibm.com/support/knowledgecenter/en/SSHSCD_8.0.0/com.ibm.worklight.dev.doc/devref/t_impl_java_adapter_JAXRS.html
Security framework in MFP v8.0:
https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/8.0/authentication-and-security

Session & Token Fixation in IBM MobileFirst Platform 7.1

We're developing a hybrid app, cordova based using MFP 7.1 It was observed that the app uses client ID as session ID. As follow in the red box
It was found that the Client ID will not be changed until reinstallation of the application. Whenever a user login on the device, its identity will be associated with the Client ID. With the Client ID, it may be able to retrieve another ID WL-Instance-ID from the application server. With valid Client ID and WL-Instance-ID, attacker will be able to access the application with the privilege of the victim user.
How to dissociate Client ID and Session ID? i.e. it should not be possible to retrieve a valid Session ID/token just by Client ID. And Session ID/token should be changed during change in security context.
We follow the instructions from here to implement the authentication
https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/7.1/authentication-security/custom-authentication/
Create mobileSecurityTest to protect adapter’s procedures; it's in SecurityTests section.
<mobileSecurityTest name="LoginAdapter-securityTest">
<testUser realm="LoginAdapterRealm" />
<testDeviceId provisioningType="none" />
<testDirectUpdate mode="disabled"/>
</mobileSecurityTest>
Use AdapterAuthenticator to handle userIdentity, and define two methods LoginAdapter.onAuthRequired, LoginAdapter.onLogout in LoginAdapter to handle security request.
<realm loginModule="LoginAdapterModule" name="LoginAdapterRealm">
<className>com.worklight.integration.auth.AdapterAuthenticator</className>
<parameter name="login-function" value="LoginAdapter.onAuthRequired" />
<parameter name="logout-function" value="LoginAdapter.onLogout" />
</realm>
Define module to create and store user identities that is used by LoginAdapterRealm; it's in loginModules section.
<loginModule name="LoginAdapterModule" expirationInSeconds="1800">
<className>com.worklight.core.auth.ext.NonValidatingLoginModule</className>
</loginModule>

How to authenticate /app/rest/** if called from another service?

Is there a builtin mechanism to authenticate /app/rest/** if the request is coming from another service ?
You can do this by spring security configuration. Try adding this configuration in SecurityConfiguration
.authorizeRequests()
.antMatchers("/app/rest/**").hasAuthority(AuthoritiesConstants.ADMIN)

Resources