spring web security questions - jsf

All,
I have my application setup so that i can use a specific username and password combination:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http use-expressions="true" access-denied-page="/start.jsf">
<intercept-url pattern="/start.jsf" filters="none" />
<intercept-url pattern="/web/**" access="isAuthenticated()" />
<form-login login-page="/start.jsf" default-target-url="/web/user/homepage.jsf" authentication-failure-url="/start.jsf?state=failure"/>
<logout logout-success-url="/start.jsf?state=logout" />
</http>
<!-- <authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="md5" />
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT U.email_address AS username, U.password as password, 'true' as enabled FROM users U where U.email_address=?"
authorities-by-username-query="SELECT U.email_address AS username, 'USER' as authority FROM users U WHERE U.email_address=?"
role-prefix="ROLE_" />
</authentication-provider>
</authentication-manager> -->
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="user1" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Problem is that when I ask it to goto the dataSource, it cannot find the datasource. Reason for this is I have another ApplicationContext.xml in a config folder where all my java source files are. How do people normally organize the project so that this file is able to pickup the datasource file? I want to setup the project accordingly...thanks for the input!
Also, the login works, however, once the user logs in, I want to be able to get the userid/password and I'm not able to. How is that possible?

Implying that you have 2 XML files (in classpath) with spring context config: main-ctx.xml and security-ctx.xml and your are instantiating your app context using main-ctx.xml.
Then you can include config from security-ctx.xml into app context using this in main-ctx.xml (depends on your files locations path may be different):
<import resource="classpath:security-ctx.xml"/>
So you can define dataSource in main-ctx.xml and use it in security-ctx.xml in authentication-manager configuration.

Related

Add-in Warning: License Information Missing or Expired

I am getting following error in Office Excel Add-in I developed using office.js, only on some machines.
Our add-in is a free. I have also found a few people complaining about this behavior for their free add-ins. It seems that this behavior is noticeable on few customer machines.
My manifest file:
<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp
xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<Id>masked</Id>
<Version>1.0.0.0</Version>
<ProviderName>Invensys Systems Inc.</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<DisplayName DefaultValue="Configuration Assistant for Wonderware Online" />
<Description DefaultValue="Execute administrative tasks against your Wonderware Online InSight subscription."/>
<IconUrl DefaultValue="https://online.wonderware.com/TagAdministrator/Images/icon-administrator-x32.png"/>
<SupportUrl DefaultValue="https://www.wonderware.com/contact/contact-support ">
<Override Locale="en-US" Value="https://www.wonderware.com/contact/contact-support " />
</SupportUrl>
<AppDomains>
<AppDomain>https://wonderware.auth0.com</AppDomain>
</AppDomains>
<Hosts>
<Host Name="Workbook" />
</Hosts>
<Requirements>
<Sets DefaultMinVersion="1.2">
<Set Name="ExcelApi" />
</Sets>
</Requirements>
<DefaultSettings>
<SourceLocation DefaultValue="https://online.wonderware.com/TagAdministrator/" />
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
</OfficeApp>
My addins from Office Store
Data Assistant for Wonderware Online InSigh
Configuration Assistant for Wonderware Online

Where do you set and access run-time configuration parameters per environment for service fabric?

For two environments, local and cloud, how would I set up custom settings or parameters for resources such as Sql databases, storage accounts, etc... Ideally it would be one parameter name called in code to say, point a DbContext towards a particular database, that in configurations for either a local or cloud environment be different. Thank you.
In order to have per environment variables for running Service Fabric locally and in the cloud this is what you must do:
Add your custom config section and parameters to the Settings.xml file of the Service/Actor project (located at \PackageRoot\Config\Settings.xml from the project root). Leave the parameters blank as we will be setting these elsewhere per environment. Here is an example one.
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
<Section Name="UserDatabase">
<Parameter Name="UserDatabaseConnectionString" Value="" />
</Section>
</Settings>
In the ApplicationManifest.xml file of your Service Fabric project, there will be <ServiceManifestImport> elements for each of your included projects. Underneath that will be a <ConfigOverrides> element where we will declare what values for our configs will be supplanted by values set per environment in the local and cloud xml files underneath ApplicationParameters in our Service Fabric project. In that same ApplicationManifest.xml file, you'll need to add the parameter that will be present in the local and cloud xml files, otherwise they'll be overwritten upon build.
Continuing with the example above, this is how it would be set.
<Parameters>
<Parameter Name="ServiceName_InstanceCount" DefaultValue="-1" />
<Parameter Name="UserDatabaseConnectionString" DefaultValue="" />
</Parameters>
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="UserDatabase">
<Parameter Name="UserDatabaseConnectionString" Value="[UserDatabaseConnectionString]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
In the local.xml and cloud.xml files underneath ApplicationParameters in your Service Fabric project, you will specify your environment specific variables like so.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="ServiceName_InstanceCount" Value="1" />
<Parameter Name="UserDatabaseConnectionString" Value="Server=(localdb)\MsSqlLocalDb;Database=Users;User=ReadOnlyUser;Password=XXXXX;" />
</Parameters>
</Application>
Finally, in your Service/Actor you can access these per-environment configuration variables like so.
var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
var connectionStringParameter = configurationPackage.Settings.Sections["UserDatabase"].Parameters["UserDatabaseConnectionString"];
You can just use environment variables just like any other application, this also works with guest executable within service fabric unlike the settings.xml as this requires the built-in service fabric runtime.
Within your application you can access environment variables just like any other .net application though the GetEnvironmentVariable method on the Environment class:
var baseUri = Environment.GetEnvironmentVariable("SuperWebServiceBaseUri");
Then we need to setup some default environment variables values, this is done within the ServiceManifest.xml manifest file of the service.
<?xml version="1.0" encoding="utf-8" ?>
<ServiceManifest Name="MyServicePkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- snip -->
<CodePackage Name="Code" Version="1.0.0">
<!-- snip -->
<EnvironmentVariables>
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="http://localhost:12345"/>
</EnvironmentVariables>
</CodePackage>
<!-- snip -->
</ServiceManifest>
These environment variable can then be overridden within the ApplicationManifest.xml file by using the following code:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<!-- snip -->
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="https://the-real-live-super-base-uri.com/"/>
</EnvironmentOverrides>
</ServiceManifestImport>
<!-- snip -->
</ApplicationManifest>
This then can be parameterised like any other application manifest setting using the local.xml and cloud.xml.
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="MyService_SuperWebServiceBaseUri" Value="https://another-base-uri.com/" />
</Parameters>
</Application>
Then we'll have to update the ApplicationManifest.xml to support these parameters;
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="MyService_SuperWebServiceBaseUri" DefaultValue="https://the-real-live-super-base-uri.com/" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
<EnvironmentOverrides CodePackageRef="Code">
<EnvironmentVariable Name="SuperWebServiceBaseUri" Value="[MyService_SuperWebServiceBaseUri]"/>
</EnvironmentOverrides>
</ServiceManifestImport>
<!-- snip -->
</ApplicationManifest>
The above answers explain well how it is done. I want to add a sidemark, why it is that 'convoluted':
It has to be this way, as the services are intended to be self-contained. They should run by default in any application they are linked into. Independent of the application's Manifest. So the service can only rely on parameters, which are at least predefined in its own configuration.
These presettings can then be overwritten by the application. This is the only universal approach.

Trying to get JSF(Faces) working within Spring WebFlow

I been trying to add some JSF(Face) code into my Spring Webflow project but I am getting the following error:
java.lang.IllegalStateException: FacesContext has not been initialized within the current Web Flow request. Check the configuration for your <webflow:flow-executor>. For JSF you will need FlowFacesContextLifecycleListener configured as one of its flow execution listeners.
Here is my flow.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.2.xsd">
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF">
<webflow:flow-location-pattern value="**/*-flow.xml" />
</webflow:flow-registry>
<!-- Configures the Spring Web Flow JSF integration -->
<faces:flow-builder-services id="flowBuilderServices" />
<!-- A listener maintain one FacesContext instance per Web Flow request. -->
<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
</beans>
and here is my flow:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var name="customer" class="org.smith.webflowtemplate.domain.Customer"/>
<view-state id="checkbox-input" model="customer" >
<transition on="submit" to="preview" validate="false"/>
<transition on="cancel" to="thanks" validate="false"/>
</view-state>
<view-state id="preview" model="customer">
<transition on="accept" to="endState"/>
</view-state>
<end-state id="endState" view="/index.jsp" />
</flow>
You need to add a Faces Context listener like this:
<flow-executor id="flowExecutor">
<flow-execution-listeners>
<listener ref="facesContextListener" />
</flow-execution-listeners>
</flow-executor>
<beans:bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

Spring Kerberos Extension, SSO and Machines Outside the Domain

I have been POC'ing with milestone 2 of the Kerberos extension to achieve single sign-on.
Quick summary of my setup:
KDC: Windows Server 2003 (SP2)
Web server: Ubuntu 10.04, Tomcat 5.5, Java 1.6.0_22 (not on the domain)
Spring: Framework 3.0.5, Security 3.0.4, Kerberos Extension 1.0.0 M2
I have setup my configuration to first attempt SPNEGO authentication and if it fails to then redirect to a login page.
This is done by setting SpnegoAuthenticationProcessingFilter's "failureHandler" property. I have successfully tested this
on Windows machines (XP and 7) that are in and out of the domain. The machines that are outside the domain gets redirected to
the login page and then can successfully login.
Here is my config:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http entry-point-ref="spnegoEntryPoint" auto-config="false">
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/j_spring_security_check*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
<form-login login-page="/login.html" default-target-url="/" always-use-default-target="true"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="kerberosServiceAuthenticationProvider" />
<authentication-provider ref="kerberosAuthenticationProvider"/>
</authentication-manager>
<beans:bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
<beans:bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<beans:property name="failureHandler">
<beans:bean class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.html" />
<beans:property name="allowSessionCreation" value="true"/>
</beans:bean>
</beans:property>
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<beans:property name="ticketValidator">
<beans:bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<beans:property name="servicePrincipal" value="HTTP/mywebserver.corpza.corp.co.za"/>
<beans:property name="keyTabLocation" value="classpath:mywebserver.keytab" />
<beans:property name="debug" value="true"/>
</beans:bean>
</beans:property>
<beans:property name="userDetailsService" ref="dummyUserDetailsService" />
</beans:bean>
<beans:bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<beans:property name="kerberosClient">
<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<beans:property name="debug" value="true" />
</beans:bean>
</beans:property>
<beans:property name="userDetailsService" ref="dummyUserDetailsService" />
</beans:bean>
<beans:bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<beans:property name="debug" value="true" />
<beans:property name="krbConfLocation" value="/etc/krb5.conf" />
</beans:bean>
<beans:bean id="dummyUserDetailsService" class="main.server.DummyUserDetailsService"/>
</beans:beans>
When the Windows machine is outside the domain my web server responds with the "WWW-Authenticate Negotiate" header (as per usual) to which
the Windows machine responds to with a NTLM header ("Negotiate TlRM..."), where the SpnegoAuthenticationProcessingFilter then says "Negotiate Header was invalid..."
and awesomly redirects the user to the login page. Great.
The Issue:
There are a number of Mac and Linux machines that are permanently outside the domain which would need to use this web app.
When they hit the web app (with Firefox 3.6) my web server responds with the expected "WWW-Authenticate Negotiate" header to inform
the client that the web app is Kerberized, BUT neither the Mac or Linux machines responds at all. Thus the SpnegoAuthenticationProcessingFilter
doesn't get entered again and hence no failure and subsequently no redirection to the login page takes place.
The Question:
Why doesn't the Mac and Linux machines respond in the same way as the Windows machines (can't belive I just asked that...)?
I know that when the Mac and Linux machines obtain a ticket (via kinit) they are able to authenticated but this doesn't seem like a good solution
at all as it requires effort from the user to provide credentials etc. where the tickets expires as well.
So is there any way that we can get these machines to send back a NTLM header as the Windows machines does?
Or if there are any other suggestions/ways please let me know.
B.t.w. I did configure the Firefoxes that I used on to test on the Mac and Linux machines ("network.negotiate-auth.delegation-uris" and "network.negotiate-auth.trusted-uris" was set to ".corpza.corp.co.za").
It doesn't look like you set network.automatic-ntlm-auth.trusted-uris. Did you read through this?
https://developer.mozilla.org/en/Integrated_Authentication
Grant
You are going the wrong way. Don't rely on the failing SPNEGO filter. The Linux and Mac clients behave correctly just as the Windows client does. The general setup should look like the following, if the filter does not implement/support that, you have found a bug.
Client sends a request to the server
Client receives "401 WWW-Authenticate: Negotiate" from the server (or any combination of Negotiate, Basic, Digest).
Client tries to supply auth data and if it fails it shows the 401 page.
Now you rely on faulty/non-processible data sent from the Windows client to present the form. You should rather send the form with the 401 directly to give all clients the ability to choose an appropriate login method (SPNEGO or form, ie. fail-through). Keep in mind that form auth is not an http auth like Negotiate, Digest or Basic. It has to be treated differently.
We are using that filter too and I am not really happy with it. So I have hands-on experience.

Require authentication through https with spring security?

I'm using tomcat 6, spring mvc 3.0.0 and spring security 3.0.0, and since the passwords I store in the database are sha1 hashed, I can't use digest authentication (section 9.2.1 of the documentation spells that out). For this reason, I need to make authentication happen through https.
Due to potential processing overhead, I want to keep as much of the traffic in regular http as possible. Is there a way I can make spring use https for unathenticated requests, then use http once authentication is done? I think this is done with a ChannelProcessingFilter of some sort, but I'm stumped as to the particulars.
Here's my application-security.xml file as it currently stands:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()" />
<http-basic />
</http>
<authentication-manager>
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder hash="sha"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="myUserDetailsService"
class="path.to.myUserDetailsServiceImpl">
</beans:bean>
</beans:beans>
Thanks for the help.
If at any point you pass a session id over HTTP you are violating OWASP A9. An attacker doesn't need the password if he has the session id. I would not implement this feature in your application, https is very light weight and I think you should look into saving resources in places that doesn't mean that your clients will be hacked.
Not sure exactly how to do it using Spring MVC but I did accomplish this using Grails with Spring Security 3...if you are interested you can see my blog post here.
Because that will not really help you...I did a quick google search and found this post which looks correct and says to configure your web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
and your applicationContext-security.xml as such:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<http>
<intercept-url pattern="/url1.htm"
access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https" />
<intercept-url pattern="/url2.htm"
access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https" />
<intercept-url pattern="/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="http" />
<anonymous />
<http-basic/>
</http>
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<beans:bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>
</beans:beans>
Also take a look at this site for more info and how to configure tomcats SSL connector.

Resources