Encrypting datasource passwords: java.lang.SecurityException: Unauthenticated caller:null - security

I'm trying to encrypt my database password using a JBOSS security domain.
The datasource is defined in oracle-ds.xml as follows:
<datasources>
<local-tx-datasource>
<jndi-name>OracleDS</jndi-name>
<connection-url>jdbc:oracle:thin:#dbhost:1521:db</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<!-- app works fine when you use unencrypted password like this
<user-name>username</user-name>
<password>unencrypted_pass</password>
-->
<!-- Use the security domain defined in conf/login-config.xml for username and encrypted password-->
<security-domain>Encrypt-my-Password</security-domain>
....etc
The login-config.xml file contains this entry:
<application-policy name="Encrypt-my-Password">
<authentication>
<login-module
code="com.mycompany.global.er.util.ErSecureIdentityLoginModule"
flag="required">
<module-option name="username">databaseUsername</module-option>
<module-option name="password">232487h4873hf4</module-option>
<module-option name="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=OracleDS</module-option>
</login-module>
</authentication>
</application-policy>
NB the ErSecureIdentityLoginModule is a class already used to encrypt / decrypt DB passwords in another application, where it works fine.
As soon as I started using this config the application throws an exception as follows when you try to access the datasource:
java.lang.SecurityException: Unauthenticated caller:null
org.jboss.security.integration.JBossSecuritySubjectFactory.createSubject(JBossSecuritySubjectFactory.java:92)
org.jboss.resource.connectionmanager.BaseConnectionManager2.getSubject(BaseConnectionManager2.java:687)
org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:495)
org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:941)
org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:89)
org.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:92)
org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:111)
org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2101)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1325)
org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34)
com.mycompany.er.batch.data.DbHelper.createEntityManager(DbHelper.java:30)
com.mycompany.er.batch.data.DbHelper.createAndBegin(DbHelper.java:49)
com.mycompany.er.basman.HibernateTransactionFilter.doFilter(HibernateTransactionFilter.java:53)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
I downloaded the source code for jboss 5.0.1GA and debugged with TRACE enabled. There is an interesting stack trace produced:
2012-03-12 18-13-40:Login failure
javax.security.auth.login.LoginException: java.lang.NullPointerException
at org.jboss.resource.security.SubjectActions$AddPrincipalsAction.run(SubjectActions.java:101)
at java.security.AccessController.doPrivileged(Native Method)
at org.jboss.resource.security.SubjectActions.addPrincipals(SubjectActions.java:139)
at org.jboss.resource.security.ConfiguredIdentityLoginModule.login(ConfiguredIdentityLoginModule.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at org.jboss.security.plugins.auth.JaasSecurityManagerBase.defaultLogin(JaasSecurityManagerBase.java:552)
at org.jboss.security.plugins.auth.JaasSecurityManagerBase.authenticate(JaasSecurityManagerBase.java:486)
at org.jboss.security.plugins.auth.JaasSecurityManagerBase.isValid(JaasSecurityManagerBase.java:365)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:160)
at org.jboss.security.integration.JBossSecuritySubjectFactory.createSubject(JBossSecuritySubjectFactory.java:9
0)
The NullPointerException refers to this line of code in org.jboss.resource.security.SubjectActions:
static class AddPrincipalsAction implements PrivilegedAction
{
Subject subject;
Principal p;
AddPrincipalsAction(Subject subject, Principal p)
{
this.subject = subject;
this.p = p;
}
public Object run()
{
subject.getPrincipals().add(p);
return null;
}
}
However this doesn't help much, and I can't understand what I'm doing wrong.
Help!

I have since got this working. I had to remove a shedload of optional jboss components but it's not 100% clear how I fixed it exactly. One possibility is that the password encryption was not correct - ie I was using the wrong library to encrypt it, so it wasn't being decrypted correctly.

Related

Bundle has invalid content in tables.sql:_create table YYY

I'm trying to deploy a service builder module on my Liferay portal. But I'm getting the error below.
Could this be caused because I already have that table on my database? The table was created manually as part of an older project, and now I'm trying to reuse that existing table.
Thanks in advance.
2019-07-24 12:09:47.770 ERROR [pipe-start
998][com_liferay_portal_upgrade_impl:97] Invocation to listener threw
exception com.liferay.portal.kernel.upgrade.UpgradeException: Bundle
com.xxxx.xxxx.service_1.0.0 [998] has invalid
content in tables.sql:_create table dbo.news ( id_ INTEGER not null
primary key,_ title VARCHAR(75) null,_ push_notification
BOOLEAN,_ date_time VARCHAR(75) null,_ short_description VARCHAR(75)
null,_ long_description VARCHAR(75) null,_ picture VARCHAR(75)
null,_ type_ VARCHAR(75) null,_ tag VARCHAR(75) null_); [Sanitized]
at
com.liferay.portal.spring.extender.internal.context.ParentModuleApplicationContextExtender$InitialUpgradeStep.upgrade(ParentModuleApplicationContextExtender.java:220)
at
com.liferay.portal.upgrade.internal.executor.UpgradeExecutor$UpgradeInfosRunnable.run(UpgradeExecutor.java:159)
at
com.liferay.portal.output.stream.container.internal.OutputStreamContainerFactoryTrackerImpl.runWithSwappedLog(OutputStreamContainerFactoryTrackerImpl.java:119)
at
com.liferay.portal.upgrade.internal.executor.UpgradeExecutor.executeUpgradeInfos(UpgradeExecutor.java:110)
at
com.liferay.portal.upgrade.internal.executor.UpgradeExecutor.execute(UpgradeExecutor.java:87)
at
com.liferay.portal.upgrade.internal.release.osgi.commands.ReleaseManagerOSGiCommands$UpgradeInfoServiceTrackerMapListener.keyEmitted(ReleaseManagerOSGiCommands.java:485)
at
com.liferay.portal.upgrade.internal.release.osgi.commands.ReleaseManagerOSGiCommands$UpgradeInfoServiceTrackerMapListener.keyEmitted(ReleaseManagerOSGiCommands.java:474)
at
com.liferay.osgi.service.tracker.collections.internal.map.ServiceTrackerMapImpl$DefaultEmitter.emit(ServiceTrackerMapImpl.java:222)
at
com.liferay.osgi.service.tracker.collections.map.PropertyServiceReferenceMapper.map(PropertyServiceReferenceMapper.java:43)
at
com.liferay.osgi.service.tracker.collections.internal.map.ServiceTrackerMapImpl$ServiceReferenceServiceTrackerCustomizer.addingService(ServiceTrackerMapImpl.java:260)
at
com.liferay.osgi.service.tracker.collections.internal.map.ServiceTrackerMapImpl$ServiceReferenceServiceTrackerCustomizer.addingService(ServiceTrackerMapImpl.java:248)
at
org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:943)
at
org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
at
org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at
org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229)
at
org.osgi.util.tracker.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:903)
at
org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:109)
at
org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:891)
at
org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:804)
at
org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:127)
at
org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:228)
at
org.eclipse.osgi.internal.framework.BundleContextImpl.registerService(BundleContextImpl.java:469)
at
org.eclipse.osgi.internal.framework.BundleContextImpl.registerService(BundleContextImpl.java:487)
at
org.eclipse.osgi.internal.framework.BundleContextImpl.registerService(BundleContextImpl.java:1004)
at
com.liferay.portal.spring.extender.internal.context.ParentModuleApplicationContextExtender$ParentModuleApplicationContextExtension._processInitialUpgrade(ParentModuleApplicationContextExtender.java:613)
at
com.liferay.portal.spring.extender.internal.context.ParentModuleApplicationContextExtender$ParentModuleApplicationContextExtension.start(ParentModuleApplicationContextExtender.java:571)
at
org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
at
org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
at
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:488)
at
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:1)
at
org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
at
org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450)
at
org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:908)
at
org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at
org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:230)
at
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:137)
at
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:129)
at
org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:191)
at org.eclipse.osgi.container.Module.publishEvent(Module.java:476)
at org.eclipse.osgi.container.Module.start(Module.java:467) at
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428)
at
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:447)
at
org.eclipse.equinox.console.commands.EquinoxCommandProvider.start(EquinoxCommandProvider.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:139)
at
org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:91)
at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:599)
at
org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:526)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:415)
at org.apache.felix.gogo.runtime.Pipe.doCall(Pipe.java:416) at
org.apache.felix.gogo.runtime.Pipe.call(Pipe.java:229) at
org.apache.felix.gogo.runtime.Pipe.call(Pipe.java:59) at
java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748) Caused by:
java.sql.SQLSyntaxErrorException: unexpected token: DBO at
org.hsqldb.jdbc.JDBCUtil.sqlException(JDBCUtil.java:376) at
org.hsqldb.jdbc.JDBCUtil.sqlException(JDBCUtil.java:247) at
org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1817) at
org.hsqldb.jdbc.JDBCStatement.executeUpdate(JDBCStatement.java:208)
at
com.zaxxer.hikari.pool.ProxyStatement.executeUpdate(ProxyStatement.java:117)
at
com.zaxxer.hikari.pool.HikariProxyStatement.executeUpdate(HikariProxyStatement.java)
at com.liferay.portal.dao.db.BaseDB.runSQL(BaseDB.java:294) at
com.liferay.portal.dao.db.BaseDB.runSQL(BaseDB.java:264) at
com.liferay.portal.dao.db.BaseDB.runSQLTemplateString(BaseDB.java:452)
at
com.liferay.portal.dao.db.BaseDB.runSQLTemplateString(BaseDB.java:509)
at
com.liferay.portal.spring.extender.internal.context.ParentModuleApplicationContextExtender$InitialUpgradeStep.upgrade(ParentModuleApplicationContextExtender.java:216)
... 59 more Caused by: org.hsqldb.HsqlException: unexpected token:
DBO at org.hsqldb.error.Error.parseError(Error.java:101) at
org.hsqldb.ParserBase.unexpectedToken(ParserBase.java:815) at
org.hsqldb.ParserBase.checkIsIrregularCharInIdentifier(ParserBase.java:335)
at org.hsqldb.ParserDQL.checkIsSchemaObjectName(ParserDQL.java:115)
at org.hsqldb.ParserDQL.readNewSchemaObjectName(ParserDQL.java:5912)
at org.hsqldb.ParserTable.compileCreateTable(ParserTable.java:78) at
org.hsqldb.ParserDDL.compileCreate(ParserDDL.java:156) at
org.hsqldb.ParserCommand.compilePart(ParserCommand.java:236) at
org.hsqldb.ParserCommand.compileStatements(ParserCommand.java:91) at
org.hsqldb.Session.executeDirectStatement(Session.java:1227) at
org.hsqldb.Session.execute(Session.java:1018) at
org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1809)
... 67 more
The fact that the table is already existing is surely the issue. Service builder deployment keep track of the "schema" version that is currently deployed, and if there is none, they create it using the sql script.
In your case, I would suggest
renaming or exporting and delete your current table
deploying your new service
move your data back to the new table created
Once this is done, don’t ever touch that data directly in the database, let your new service handle all future interaction. In fact, it might even be better to import the old data using the service API.

Standalone Connection to JBoss EJB with Custom Login Module

I have a custom login module defined in JBoss EAP 6.4.0.GA (AS 7.5.0.Final-redhat-21).
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/MySQLDS"/>
<module-option name="principalsQuery" value="SELECT password FROM xxx.User WHERE name=?"/>
<module-option name="rolesQuery" value="SELECT r.name, 'Roles' FROM xxx.Role r JOIN xxx.User_Roles ur ON r.id=ur.role_id JOIN xxx.User u ON ur.user_id=u.id WHERE u.name=?"/>
<module-option name="hashAlgorithm" value="SHA-256"/>
<module-option name="hashEncoding" value="hex"/>
<module-option name="password-stacking" value="useFirstPass"/>
It (successfully) connects to MySQL to retrieve the username, password and role. The EJB is annotated with #RolesAllowed(value = "Administrator")
#SecurityDomain(value = "xxx"). When I connect to the EJB using a web application or using a Web Service with basic authentication it connects fine (still now). The user is properly authenticated. However, using the following "standalone" code I cannot authenticate the user:
final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(
this.properties);
final ConfigBasedEJBClientContextSelector selector = new ConfigBasedEJBClientContextSelector(
ejbClientConfiguration);
EJBClientContext.setSelector(selector);
final Context context = new InitialContext(this.properties);
final String ejbConnectionString = ejbConnectionInformation.getEJBConnectionString();
final T ejbInterface = (T) context.lookup(ejbConnectionString);
ejbConnection = new EJBConnection<T>(context, ejbInterface);
...
The ejb properties are as follows:
remote.connections = default
remote.connection.default.host = localhost
remote.connection.default.port = 4447
remote.connection.default.username = <username>
remote.connection.default.password = <plain text password>
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED = false
java.naming.factory.url.pkgs = org.jboss.ejb.client.naming
I've also tried various combinations of:
#remote.connection.default.protocol=http-remoting
#jboss.naming.client.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
#remote.connection.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
#remote.connection.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
#jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=true
#jboss.naming.client.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
#jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
After turning on JBoss logging I see it fails because the password is incorrect, namely:
TRACE [org.jboss.security] (EJB default - 2) PBOX000236: Begin initialize method
DEBUG [org.jboss.security] (EJB default - 2) PBOX000281: Password hashing activated, algorithm: SHA-256, encoding: hex, charset: null, callback: null, storeCallBack: null
TRACE [org.jboss.security] (EJB default - 2) PBOX000262: Module options [dsJndiName: java:jboss/datasources/MySQLDS, principalsQuery: SELECT password FROM xxx.User WHERE name=?, rolesQuery: SELECT r.name, 'Roles' FROM xxx.Role r JOIN xxx.User_Roles ur ON r.id=ur.role_id JOIN xxx.User u ON ur.user_id=u.id WHERE u.name=?, suspendResume: true]
TRACE [org.jboss.security] (EJB default - 2) PBOX000240: Begin login method
TRACE [org.jboss.security] (EJB default - 2) PBOX000263: Executing query SELECT password FROM xxx.User WHERE name=? with username <username>
DEBUG [org.jboss.security] (EJB default - 2) PBOX000283: Bad password for username <username>
TRACE [org.jboss.security] (EJB default - 2) PBOX000244: Begin abort method
DEBUG [org.jboss.security] (EJB default - 2) PBOX000206: Login failure: javax.security.auth.login.FailedLoginException: PBOX000070: Password invalid/Password required
at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:286) [picketbox-4.1.1.Final-redhat-1.jar:4.1.1.Final-redhat-1]
I should mention that the same exact code properly connected to the EJB before I added the JBoss login module and the security annotations on the EJB.
It should also be noted that if I change the username to one that is not stored in the database I get a different error, so this proves that it is getting to the database, but that the problem really is one where the password is not correctly matched somehow, even though it perfectly matches the 'hashed' version in the database. I've also tried adding the 'hashed' version to the ejb properties without success.
DEBUG [org.jboss.security] (EJB default - 1) PBOX000206: Login failure: javax.security.auth.login.FailedLoginException: PBOX000062: No matching username found found in principals
I've also tried upping the versions of jboss-remote-naming from 2.0.3.Final to 2.0.4.Final, xnio-nio from 3.3.0.Final to 3.3.2.Final, and jboss-ejb-client from 1.0.28.Final to 1.0.31.Final, but I get the same result, "Password invalid/password required".
I'll be very happy for any ideas because I've tried just about everything the Internet has to say on the subject.
OK, it is working now. The missing parts were:
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=true
remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
NB: replace "default" in the above with whatever you configured in "remote.connections".
In the "security-realms" section of "standalone.xml" or equivalent enter the following:
<security-realm name="xxxRealm">
<authentication>
<jaas name="xxx"/>
</authentication>
</security-realm>
Where "xxx" is the name of the "security-domain". To configure remoting add the following:
<subsystem xmlns="urn:jboss:domain:remoting:1.2">
<connector name="remoting-connector" socket-binding="remoting" security-realm="xxxRealm"/>
</subsystem>
Then add the following to your "security-domain" (this is assuming like you have a "DatabaseServiceLoginModule" like above:
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
Credit goes to the following which had the missing/correct configuration properties: https://community.jboss.org/wiki/JBossAS7RemoteEJBAuthenticationHowto

MVC 5 Forms authentication retuns null for User.Identity.Name

Authentication fails to authenticate for forms authentication in my MVC 5 application. Page gets redirected correctly, but User.Identity.IsAuthenticated and User.Identity.Name values are empty.
My webconfig,
<system.web>
<authentication mode="Forms">
<forms cookieless="UseCookies" defaultUrl="~/" loginUrl="~/user/signin" name="MYAPPWeb" timeout="21600" slidingExpiration="true"/>
</authentication>
UserController,
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult SignIn(SignInViewModel user)
{
UserDTO userObj;
using (var services = new ServiceFactory())
{
userObj = services.UserManagement.ValidateLoginDetails(ConfigHelper.EnvironmentString, user.TenantName, user.Username, user.Password);
}
string userID = userObj.UserID.ToString();
//FormsAuthentication.RedirectFromLoginPage(userID, user.RememberMe);
FormsAuthentication.SetAuthCookie(userID.ToString(),true);
FormsAuthentication.RedirectFromLoginPage(userID, false); //DO NOT REMEMBER ME
}
HomeController (Default page)
public ActionResult Index()
{
bool x = User.Identity.IsAuthenticated; //false?
string y = User.Identity.Name; //null?
return View();
}
It looks pretty straight forward, am I missing something? Please help!
Note:
When I create the project I selected windows authentication. It created some Owin authenticaiton related configuration cs files (startup.auth.cs). I have removed them and added the above appsetting entry as it is required to stop loading Owin assemblies.
<add key="owin:AutomaticAppStartup" value="false"/>
If your project has Owin authentication by default, it will remove form authentication from the project.
If you see your web config you may see
<remove name="FormsAuthentication" />
configuration.
Simply remove it.
I had the same problem and it solved the issue.

SignedXml.CheckSignature(key) always throws error

I am new to C#.NET programming. With help of online references, I have written the code below to verify signature of a SAML assertion (generated by a server API).
My Env:
VS 2010 Ver4.0
Win XP SP3
SAML Assertion token looks something like this:*
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="idGYEv...USb8GfnqF" IssueInstant="2012-12-05T14:13:39.00Z">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://noszti...xyz.com</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>uDeAjOE/iCa6Pfz5oOjaOMtAQe4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>IGjZX...LaEMzA=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIE...cg6A==</X509Certificate>
<X509SubjectName>emailAddress=xmlsec#aleksey.com,CN=Aleksey Sanin,OU=Test Root Certificate,O=XML Security Library (http://www.aleksey.com/xmlsec),ST=California,C=US</X509SubjectName>
</X509Data>
</KeyInfo>
</Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">admin</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2012-12-05T14:19:39.00Z" Recipient=""/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2012-12-05T14:13:39.00Z" NotOnOrAfter="2012-12-05T14:19:39.00Z">
<saml:AudienceRestriction>
<saml:Audience/>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2012-12-05T14:13:39.00Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
My code snippet to verify signature:
//Load the SAMLAssertionToken in XML Document
XmlDocument xDoc = new XmlDocument();
xDoc.PreserveWhitespace = false;
xDoc.LoadXml(SAMLAssertionToken); //SAMLAssertionToken above
//Retrieve the public key from certificate available to end user
X509Certificate2 X509Cert = new X509Certificate2("D:/Schemas/X509Certificate.cer");
RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)X509Cert.PublicKey.Key;
//Signature Verification Starts. Find the Signature element
XmlNamespaceManager xMan = new XmlNamespaceManager(xDoc.NameTable);
xMan.AddNamespace("ns", "urn:oasis:names:tc:SAML:2.0:assertion");
xMan.AddNamespace("ns1", "http://www.w3.org/2000/09/xmldsig#");
XmlElement SigElm = (XmlElement)xDoc.SelectSingleNode("//ns:Assertion//ns1:Signature", xMan);
//Create SignedXml object and load signature for verification
SignedXml sig = new SignedXml(xDoc);
sig.LoadXml(SigElm);
bool verified = sig.CheckSignature(rsaKey);
if (verified)
{
Console.WriteLine("Signature verified successfully");
}
else
{
Console.WriteLine("Signature not valid");
}
On running the code, it throws an error "SignatureDescription could not be created for the signature algorithm supplied."
on line: bool verified = sig.CheckSignature(rsaKey);
On debugging, Signature is correctly assigned to SigElm.
Note: the certificate retrieved from "X509Certificate.cer" is exactly the same as that displayed in element of the signature (in SAML Assertion). So it looks like a valid and matching certificate. The certificate in SAML assertion token is signed with a private key; so I am using the public key from "X509Certificate.cer" (certificate available to end users) to verify the signature (in SAML assertion).
I also tried to verify the signature using:
bool verified = sig.CheckSignature(X509Cert, true);
but it throws the same error.
I tried few approaches (using online references for this error) but unable to figure out the problem.
Pls advise...

jsf spring security session timeout viewExpiredException

I have the following problem with the timeouts in Spring Security with JSF:
I've customized the sessionmanagement filter so that the user is redirected to the invalidSessionUrl just if the requested page is secured (i.e. if it is allowed just for authenticated users). The custom code I put into the session management filter provided by Spring Security is:
if (invalidSessionUrl != null) {
String pagSolicitada = UtilSpringSecurity.extraerPagina(request);
if ( UtilSpringSecurity.paginaAutenticada(pagSolicitada ) ) {
request.getSession();
redirectStrategy.sendRedirect(request, response, invalidSessionUrl);
return;
}
//the requested page doesn't require the user to be authenticated
//so i just skip this filter and continue with the filter chain
chain.doFilter(request, response);
return;
}
The method "UtilSpringSecurity.extraerPagina(request)" returns the requested page this way:
public static String extraerPagina (HttpServletRequest request) {
String uri = request.getRequestURI().toLowerCase();
String cPath = request.getContextPath().toLowerCase();
// uri = cPath + pagina
int longCPath = cPath.length();
String pagina = uri.substring(longCPath);
return pagina;
}
And the method "UtilSpringSecurity.paginaAutenticada(pagSolicitada)" returns true if the the param is a page that requires the user to be authenticated (I do the check with IFs, considering the intercept-url elements of my xml security config file which have the attribute access="isAuthenticated()"):
public static boolean paginaAutenticada (String pagina) {
if (pagina.startsWith("/faces/paginas/administracion/") || pagina.startsWith("/faces/paginas/barco/") ) {
return true;
}
return false;
}
This solution works, but it has just one problem:
If I leave the browser staying idle at a page until the session timeout expires, and then I request the same page, then I get a "viewExpiredException". This is because the filter worked well, it bypassed the redirection to the invalidSessionUrl, but as the session expired anyway, then I get that exception trying to re-render the same page.
If I request any other unsecured page when the session timout has expired, it works well, it redirects correctly to the page and I don't get the viewExpiredException.
Anyone knows how to solve this?
Thank you in advance.
Spring security should give you anonymous access to sets of pages for an un-authenticated user. Below is an excerpt of my XML configuration for how I achieved this.
<http auto-config="true" access-denied-page="/unauthorized.xhtml" >
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/app/**" access="ROLE_USER,ROLE_ADMIN" />
<intercept-url pattern="/*.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page="/login.xhtml" login-processing-url="/j_spring_security_check"
authentication-success-handler-ref="authenticationSuccessBean"
authentication-failure-handler-ref="authenticationFailureBean" />
<session-management invalid-session-url="/login.xhtml" >
</session-management>
</http>
I essentially use intercept-url tags to claim that pages within certain relative contexts can only be accessed by the following roles. You can see that all pages at the web application default context are available to anonymous users. If the user is unauthorized to view the page then they will be redirected to access-denied-page.
The only catch is that your User bean has to implement the UserDetails interface and have a property that returns a role bean which implements the GrantedAuthority interface. Spring will look for a UserDetails to have a GrantedAuthority property to determine what the role is. If this user does not exist, is unauthenticated, or unknown then it will default to anonymous role.
Finally I solved it. It's a JSF issue, nothing to do with Spring Security.
I've overriden the restoreView method of jsf this way:
#Override
public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
UIViewRoot root = wrapped.restoreView(facesContext, viewId);
if(root == null) {
root = createView(facesContext, viewId);
}
return root;
}
Now the problem is that if the page had parameters, I lost them when I do the post to the recently created view, but that's another distinct issue (PRG pattern) dealing again with JSF.

Resources