Call from MDB to SSB is always anonymous in JBoss AS7/EAP6 - jboss7.x

Got problem with JBoss AS7 / EAP6. In MDB, when I lookup for SSB and call its method, the call is always anonymous, i.e. sessionContext.getCallerPrincipal() returns Principal(anonymous). Always... In AS5 everything was fine.
How can I fix it to make a call with an authenticated user?
My MDB:
#MessageDriven(activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/piQueue"),
#ActivationConfigProperty(propertyName = "dLQMaxResent", propertyValue = "3")
})
#SecurityDomain("mySecurityDomain")
public class PIMessageBean implements MessageListener {
...
**//subject always anonymous...**
Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
PIManager pim = lookupPIManager();
pim.getPIs(); **//call is anonymous**
...
}
My queue settings:
<subsystem xmlns="urn:jboss:domain:messaging:1.2">
<hornetq-server>
...
<jms-destinations>
<jms-queue name="piQueue">
<entry name="queue/piQueue"/>
<entry name="java:jboss/exported/jms/queue/piQueue"/>
</jms-queue>
</jms-destinations>
<security-domain>mySecurityDomain</security-domain>
</hornetq-server>
</subsystem>
My Security Domain:
<security-domain name="mySecurityDomain" cache-type="default">
<authentication>
<login-module code="com.qu.vad.CustomUsernamePasswordLoginModule" flag="required">
</login-module>
</authentication>
</security-domain>

Solved the problem by doing JAAS login in MDB

Related

Search user in LDAP(Wildfly)

My application is using LDAP for user loging.
Wildfly config:
<security-domain name="LDAPAuth">
<authentication>
<login-module code="LdapExtended" flag="required">
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
....
</login-module>
<login-module name="Database-role" code="Database" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
.....
</login-module>
<login-module name="Database-default" code="Database" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
....
</login-module>
</authentication>
</security-domain>
My question is how to search ldap users in app? I want to add possibility to search other users in ldap(for already logged users).
You could connect to WildFly management API and read security domain configuration, but you should not do this.
Don't mix server management configuration and application configuration if you have other way.
Provide the LDAP configuration to application (e.g. context parameters in the deployment descriptor or use a property file) and then do sth. like:
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapUrl);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, password);
final LdapContext ctx = new InitialLdapContext(env, null);
final SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<?> namingEnum = ctx.search("dc=mycompany,dc=example", "(uid=*)", searchControls);
while (namingEnum.hasMore()) {
// TODO
}
namingEnum.close();
ctx.close();

activemq User is not authorized to create: topic://ActiveMQ.Advisory.Connection

I am trying to use authorization in activemq, but stuck for some time now.
Here is my java code, everything works fine when I remove the authorization plugin. I am trying to create a topic named "room2".
Context jndiContext = new InitialContext();
ConnectionFactory connectionFactory;
connectionFactory = (ConnectionFactory) jndiContext
.lookup("ConnectionFactory");
connection = connectionFactory.createConnection("system", "manager");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic t = session.createTopic("room2");
Here is my activemq.xml :
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="manager"
groups="admins,publishers,consumers"/>
<authenticationUser username="user" password="password"
groups="admins,users,publishers"/>
<authenticationUser username="guest" password="password" groups="guests"/>
</users>
</simpleAuthenticationPlugin>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic="room2" read="consumers" write="publishers" admin="admins" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
This is the error that I get :
User system is not authorized to create: topic://ActiveMQ.Advisory.Connection
If I use <authorizationEntry topic=">" read="consumers" write="publishers" admin="admins" />, then it works fine, so what exactly does > mean?
You need to assign roles to allow for the creation of Advisory Topics unless you just disable them. An example from the website is below.
<authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/>
Refer to the documentation here.

How to register the custom SSL certificate of X509TrustManager in Jboss AS7

Is there anybody to know how to register a custom SSL certificate of X509TrustManager in Jboss 7?
As the requirement of my project, I need to customize the default behavior of SSL certificate on X509TrustManager. I already have a custom certificate by extending X509TrustManager and override the default behavior, but now I do not know to register this custom file that Jboss AS7 can understand my own file instead of default X509TrustManager.
public class MyManager implements com.sun.net.ssl.X509TrustManager {
public boolean isClientTrusted(X509Certificate[] chain) { return true; }
public boolean isHostTrusted(X509Certificate[] chain) { return true; }
...
}
Thanks
If you have a security domain you can change the behavior of the Trust Manager in this way:
<security-domain name="CertificateDomain">
<authentication>
<login-module code="CertificateRoles" flag="required">
<module-option name="securityDomain" value="CertificateDomain"/>
<module-option name="verifier" value="org.jboss.security.auth.certs.AnyCertVerifier"/>
....
</login-module>
</authentication>
<jsse keystore-password="..." keystore-url=".." truststore-password="..." truststore-url="..." truststore-provider="..."/>
</security-domain>
truststore-provider Provider of the truststore. The default JDK provider for the truststore type is used if this attribute is null
Security subsystem configuration
Another way is to add the file standalone.xml the following properties (not tested)
<system-properties>
<property name="javax.net.ssl.trustStoreProvider" value="..."/>
<system-properties>

Accessing Authentication variable from LogoutHandler or LogoutFilter in Spring security

In one of my project I have configured Spring Security to handle user authentication.
My config file looks like this:
<http use-expressions="true">
<intercept-url pattern="/" access="permitAll()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login default-target-url="/main" login-page="/" always-use-default-target="true" username-parameter="userId" password-parameter="password" />
<custom-filter ref="customLogoutFilter" position="LOGOUT_FILTER"/-->
<session-management invalid-session-url="/" session-authentication-strategy-ref="sas" />
</http>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" />
<beans:bean id="customLogoutHandler" class="com.somepack.CustomLogoutHandler"/>
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg index="0" ref="customLogoutHandler"/>
<beans:constructor-arg index="1" ref="customLogoutFilter"/>
<beans:property name="filterProcessesUrl" value="/"/>
</beans:bean>
<beans:bean id="customLogoutFilter" class="com.somepack.CustomLogoutFilter">
<beans:property name="reportDir" value="/tmp/reports"/>
</beans:bean>
My CustomLogoutFilter class looks like
public class CustomLogoutFilter implements LogoutHandler {
private String reportDir;
public String getReportDir() {
return reportDir;
}
public void setReportDir(String reportDir) {
this.reportDir = reportDir;
}
#Override
public void logout(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) {
String userName = authentication.getName();
File folder = new File(reportDir, userName);
deleteDir(folder); //delete function to delete Logged User specific directory
logService.info("Logout", userName, EventCode.LOGOUT,
String.format("User %s logged out successfully", userName));
for (Cookie cookie : request.getCookies()) {
printcookies(cookie);
if (cookie.equals("JSESSIONID")) {
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
request.getSession().invalidate();
}
}
But this piece of code is not working as the filter is getting called at the very first request for the Login page (even it may would get called in every request) and I am getting an NullPointerException in the
String userName = authentication.getName() line.
In fact instead of Using LogoutFilter if I use Logouthandler, I get the same error:
My handler looks like this:
public class CustomLogoutHandler extends AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler{
private String reportDir;
public String getReportDir() {
return reportDir;
}
public void setReportDir(String reportDir) {
this.reportDir = reportDir;
}
#Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException,
ServletException {
String userName = authentication.getName();
File folder = new File(reportDir, userName);
deleteDir(folder);
logService.info("Logout", userName, EventCode.LOGOUT, String.format("User %s logged out successfully", userName));
super.handle(request, response, authentication);
}
and config file changed to:
<http use-expressions="true">
<intercept-url pattern="/" access="permitAll()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login default-target-url="/main" login-page="/" always-use-default-target="true" username-parameter="userId" password-parameter="password" />
<logout delete-cookies="JSESSIONID" invalidate-session="true" success-handler-ref="customLogoutHandler" logout-url="/logout" />
<session-management invalid-session-url="/" session-authentication-strategy-ref="sas" />
</http>
<beans:bean id="customLogoutHandler" class="sequent.ui.security.CustomLogoutHandler">
<beans:property name="reportDir" value="/tmp/reports" />
</beans:bean>
Not sure how can I resolve this issue.
Please help.
In short my basic requirement is that, I need to access the User Principal in the Logout mechanism which triggered when either User clicks on the Logout button or the session expires. I need the User information because the application creates temporary folder in the name of logged user which I need to delete at the time when he log off.
Appreciate your help please!!
-Raul
You have set the filerProcessesUrl of the LogoutFilter to "/" which means that every time a user browses to the domain root, the filter will attempt to logout the user. Use a specific logout URL (or the default value) and check whether the user is actually authenticated before you try to do a logout (make sure the Authentication instance isn't null).
If you need to deal with session timeouts, where the user fails to logout, then you will also have to implement an HttpSessionListener which identifies the user from the session and performs whatever clean-up you need. This would be added to your web.xml file. Note that this class isn't invoked during a user request, so you can't use the SecurityContext to obtain information about the user, you must get it from the session object which is passed to the listener before the session is invalidated.

Jboss application-policy ignored in mutual/client-cert auth with PBESecurityDomain

With the following, mutual client cert, SSL (TLS) handshake works for a rest endpoint (yay!) - validated via testing and debugging: javax.net logging & wireshark. But...
1st observation: HTTPServletRequest and JAX-RS annotated SecurityContext has null Principal info
2nd observation: Tampering with the login-config.xml, containing application-policy elements, has no effect
In short, TLS works but the transfer of the cert DN to the HTTPServletRequest object in the request thread does not preventing the application from picking up on the caller's ID. Does anyone have any advice?
On JBoss 6:
deploy/jbossweb.sar/server.xml:
<Connector protocol="HTTP/1.1" debug="10"
SSLEnabled="true"
...
secure="true"
clientAuth="true"
sslProtocol = "TLS"
securityDomain="java:/jaas/mydomain"
SSLImplementation="org.jboss.net.ssl.JBossImplementation" />
deploy/jbossweb.sar/META-INF/jboss-beans.xml:
<depends>jboss.security:service=PBESecurityDomain</depends>
deploy/security-service.xml:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.security.plugins.JaasSecurityDomain"
name="jboss.security:service=PBESecurityDomain">
<constructor> <arg type="java.lang.String" value="mydomain"/>
</constructor>
<attribute name="KeyStoreURL">${jboss.server.home.dir}/mykeystore.jks</attribute>
<attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/mykeystorepass.pbe</attribute>
<attribute name="TrustStoreURL">${jboss.server.home.dir}/mytruststore.jks</attribute>
<attribute name="TrustStorePass">password</attribute>
<attribute name="Salt">abunchofrandomchars</attribute>
<attribute name="IterationCount">13</attribute>
<depends>jboss.security:service=JaasSecurityManager</depends>
</mbean>
</server>
deploy/security/security-jboss-beans.xml:
<bean name="XMLLoginConfig" class="org.jboss.security.auth.login.XMLLoginConfig">
<property name="configResource">login-config.xml</property>
</bean>
<bean name="SecurityConfig" class="org.jboss.security.plugins.SecurityConfig">
<property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
<property name="defaultLoginConfig"><inject bean="XMLLoginConfig"/></property>
</bean>
conf/login-config.xml:
<application-policy name="mydomain">
<authentication>
<login-module code="org.jboss.security.auth.spi.BaseCertLoginModule"
flag = "required">
<module-option name="password-stacking">useFirstPass</module-option>
<module-option name="securityDomain">java:/jaas/mydomain</module-option>
<module-option name="verifier">org.jboss.security.auth.certs.AnyCertVerifier</module-option>
<module-option name="principalClass">org.jboss.security.auth.certs.SubjectDNMapping</module-option>
</login-module>
<login-module code="org.jboss.security.auth.spi.UserRolesLoginModu"
flag = "required">
<module-option name="password-stacking">useFirstPass</module-option>
<module-option name="usersProperties">users.properties</module-option>
<module-option name="rolesProperties">roles.properties</module-option>
</login-module>
</authentication>
</application-policy>
war/WEB-INF/jboss-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC
"-//JBoss//DTD Web Application 2.4//EN"
"http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd">
<jboss-web>
<security-domain>java:/jaas/mydomain</security-domain>
<context-root>/myapp</context-root>
</jboss-web>
Add the special ClientLoginModule to login-context.xml to fix the null principal issue.
<login-module code="org.jboss.security.ClientLoginModule" flag="required"></login-module>