Symfony2 using http-basic and preauthentication together - security

What do I need
In my application I have a following schema
users (id(PK), username, email(unique), password, etc)
devices (id(PK), device_id, status, user_id)
Relation
user HAS ONE device
The application needs to support basic authentication in two variations.
Variation one: Normal, email as username and password. This approach will be used by the admin console. The admin console just like an webapp.
Variation two: email as username, device id as password. This approach will be used by mobile application. During the authentication process from device, it will pass the device id as password. Since a user will have only device at a time, the authentication process will match the device id and email to identify the user.
What I tried?
I have basically followed symfony tutorial on api key based authentication for the second variation and http-basic for the first. Please find my security.xml below.
Here, I need the firewall setup to pass when any of the underlying authentication mechanism passes. For instance, in case of web authentication, only http-basic will pass, in case of device login only simple-preauth will pass.
security.xml
<srv:container xmlns="... ...">
<config>
<firewall name="resource" pattern="^/" stateless="true">
<http-basic realm="Webservice" />
<simple-preauth authenticator="device_authenticator" />
</firewall>
<provider name="administrators">
<entity class="AppBundle\Entity\User" property="email"/>
</provider>
<provider name="device_id_user_provider" id="device_id_user_provider" />
<encoder class="AppBundle\Entity\User" algorithm="bcrypt" cost="12"/>
</config>
</srv:container>
services.xml
<container xmlns="... ...">
<services>
<service id="device_id_user_provider"
class="AppBundle\Security\DeviceIdUserProvider">
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
<service id="device_authenticator" class="AppBundle\Security\DeviceAuthenticator">
<argument type="service" id="device_id_user_provider" />
</service>
</services>
</container>
My problem
For every request the firewall tries to pass both of the authentication mechanisms. Hence its always responding with 401.
Did I set this up in a wrong way?
Or a firewall MUST pass all of its underlying auth mechanisms?
Or this is happening only because of using preauthentication?
Any recommended approach to achieve this?

Related

AADSTS700016: UnauthorizedClient_DoesNotMatchRequest

Not sure if this is the right place to ask but... We have an older application that is set up to use SSO, currently Azure ADFS. I want to use login.microsoft.com url instead of our organizational url that has been used in the past.
I replaced the currently working links in web.config with the endpoints from Azure
<appSettings>
<add key="FederationMetadataLocation" value="https://login.microsoftonline.com/dfmi.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml" />
</appSettings>
and
<federatedAuthentication>
<wsFederation passiveRedirectEnabled="true" issuer="https://login.microsoftonline.com/0845a734g7-6d23-7c96-9f4x-3427v39n4sd5/wsfed/" realm="https://customdfmi.dfmi.net/" requireHttps="true" />
<cookieHandler requireSsl="false" />
</federatedAuthentication>
I get to the sign-in page. When I put in the credentials it shows "AADSTS700016: Application with identifier 'https://customdfmi.dfmi.net/' was not found in the directory".
It is set up in Azure. Redirect URI is the exact copy of what's in web.config. What am I putting wrong in web.config? Do I need to put the Application ID somewhere in it? Any pointers would be great. Thanks!
Did you received this message?
AADSTS700016
UnauthorizedClient_DoesNotMatchRequest - The application wasn't found in the directory/tenant.
This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have misconfigured the identifier value for the application or sent your authentication request to the wrong tenant.

Membership for external users in Sitecore 8

I want to build a user registration store for Sitecore 8 website. The users will go in an external database.
Sitecore.NET 8.0 (rev. 150223)
.NET Framework 4.0.30319.18052
Razor Version=3.0.0.0
MVC 5.2.3.0
Asp.net MVC comes with the membership built in (AccountController, views, etc). I wanted to port this to my Sitecore project. The problem is Sitecore also uses membership internally. I know there is a way for getting membership working for the Sitecore 6.x versions through the switching providers described at Sitecore authenticate users against external membership database.
Is it still the same process for Sitecore 8?
This still applies to Sitecore 8 and the core asp.net membership features and the switching membership provider can still be used. The mongo db side of Sitecore 8 is for xDb, but you still use membership systems to authenticate.
I won't provide any further detail as the post you referenced seems to cover it all. Just in case there's another good post here:
https://himadritechblog.wordpress.com/2014/11/24/sitecore-custom-membership-provider/
Make sure you declare a new domain for you membership system in your domains.config.
I ended up not using the SimpleMembership and just going with Membership. I could not get the adapter that the thecodeking link mentions to work.
This method is not properly documented. I just had to change the config files. I did not have to create a custom class that inherits from MembershipProvider.
Web.config:
In membership section,
change realProviderName to "switcher"
copy "sql" node and change name and connectionStringName to "external"
In switchingProviders section,
add "external" node with domains "external"
web.config:
<membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
<providers>
<clear />
<!-- change realProviderName to "switcher" -->
<add name="sitecore"
type="Sitecore.Security.SitecoreMembershipProvider, Sitecore.Kernel"
realProviderName="switcher"
providerWildcard="%"
raiseEvents="true"
/>
<add name="sql"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="core"
applicationName="sitecore"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="256"
/>
<add name="switcher"
type="Sitecore.Security.SwitchingMembershipProvider, Sitecore.Kernel"
applicationName="sitecore"
mappings="switchingProviders/membership"
/>
<!-- copy "sql" node and change name and connectionStringName to "external" -->
<add name="external"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="external"
applicationName="sitecore"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="256"
/>
</providers>
</membership>
<switchingProviders>
<membership>
<provider providerName="sql" storeFullNames="true" wildcard="%" domains="*" />
<!-- add "external" node with domains "external" -->
<provider providerName="external" storeFullNames="true" wildcard="%" domains="external" />
</membership>
</switchingProviders>
ConnectionStrings.config:
add connection "external"
config:
<add name="external" connectionString="..." providerName="System.Data.SqlClient"/>
Domains.config:
add domain "external"
config:
<domain name="external" ensureAnonymousUser="false" />
Then use the "external" provider directly which saves user to external db. This is the key point.
// uses "external" provider directly
Membership.Providers["external"].CreateUser(...)
Instead of this which saves to core db.
// uses default provider
Membership.CreateUser(...)
I personally like to keep the membership logic very simple and away from custom providers. Sitecore has a concept of Virtual User that you can instantiate once you authenticate on the external DB. You can set any custom properties on this virtual user and let sitecore record it in xDB.
Here is a good example.

Unable to authenticate on SharePoint Online using the BizTalk SharePoint adapter

I have the following issue when using BizTalk 2013 ("R1") and SharePoint Online:
I have a static send port configured to add data to one specific list in a list in a SharePoint Online environment.
I have authentication setup using the username and password and I'm 100% sure this is a correct username and password. I'm able to login using the same credentials via a browser without problem.
FYI: the account used is a "Microsoft" only account, so not listed as an organizational (work/school) account as well.
Whenever I try to send something to the list, I get the following error:
A message sent to adapter "Windows SharePoint Services" on send port "SP_SharePointOnline" with URI "wsss://company.sharepoint.com:443/sites/poc/Biztalk-Demo/TR/Lists/List%%201" is suspended.
Error details: [System.ServiceModel.CommunicationObjectFaultedException] The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
This error was triggered by the Windows SharePoint Services receive location or send port with URI wsss://company.sharepoint.com:443/sites/poc/Biztalk-Demo/TR/Lists/List%%201.
Windows SharePoint Services adapter event ID: 12310
I have enabled WCF and WIF tracing in the BizTalk BTSNTSvc.exe and BTSNTSvc.exe.config as follows:
<system.diagnostics>
<sources>
<source name="Microsoft.IdentityModel" switchValue="Verbose">
<listeners>
<add name="wif" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
<listeners>
<add name="wcf" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\logs\WCF64.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="wcf" />
<add initializeData="C:\logs\WIF64.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="wif" />
</sharedListeners>
I get WCF logging, but I don't have any WIF logging (as I would expect).
The WCF logging provided the following as to why the channel faults (extract from WCF Trace Viewer):
<S:Fault>
<S:Code>
<S:Value>S:Sender</S:Value>
<S:Subcode>
<S:Value>wst:FailedAuthentication</S:Value>
</S:Subcode>
</S:Code>
<S:Reason>
<S:Text xml:lang="en-US">Authentication Failure</S:Text>
</S:Reason>
<S:Detail>
<psf:error>
<psf:value>0x80048821</psf:value>
<psf:internalerror>
<psf:code>0x80041012</psf:code>
<psf:text>The entered and stored passwords do not match.
</psf:text>
</psf:internalerror>
</psf:error>
</S:Detail>
</S:Fault>
As said: I'm 100% sure this is the correct username and password!
I'm stuck here, anyone able to help me out or point me in the right direction?
Why don't I have any WIF logging?
Regards,
I think there is a problem in your URL. what if you try to use in the utl the link to your sharepoint site and the name of your List as "Destination Folder URL".
you can check this walkthrough

Authorization token passed by user Invalid. Azure Cache

Maybe I'm misunderstanding how to create a cache but none of the the IDs or Access keys is working on the to enable the azure cache. I've gone through the following tutorials:
http://msdn.microsoft.com/en-us/library/windowsazure/gg618003.aspx
http://msdn.microsoft.com/en-us/wazplatformtrainingcourse_buildingappswithcacheservice_topic3#_Toc310505080
http://msdn.microsoft.com/en-us/library/windowsazure/gg618003.aspx
And about 1/2 a dozen different how to create a cache in azure pages and I'm still getting.
Authorization token passed by user Invalid.
I've got a website and cloud service with linked storage and nowhere can I find a url "yourcachename.cache.windows.net" or an Authentication Token in the manage Azure portal. Any suggestions would be greatly appreciated.
It turns out that I was getting confused between versions of Azure. I'm not sure what version this started in but I was working in 1.8 and I did not need an access key. Once I added the below sections to the web.config everything worked.
<dataCacheClients>
<dataCacheClient name="default">
<autoDiscover isEnabled="true" identifier="{your cache worker role}" />
<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300" />
</dataCacheClient>
</dataCacheClients>
<cacheDiagnostics>
And then in order to get Sessions to work I needed to add this:
<sessionState mode="Custom" customProvider="AFCacheSessionStateProvider">
<providers>
<add name="AFCacheSessionStateProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheSessionState"/>
</providers>
</sessionState>
You need to login to the old portal via the link on the new portal, click on shared caching, service bus and access control. Create/Select a namespace and the auth token would be displayed on the right hand side bar.

SharePoint and <identity impersonate="false" />

I would like to use integrated authentication to access a SQL database from a web part. It should use the IIS Application pool identity.
By default you will get the error:
System.Data.SqlClient.SqlException: Login failed for user 'SERVER\IUSR_VIRTUALMACHINE'.
Because in web.config impersonation is set to true:
<identity impersonate="true" />
I can set this to false and the database code will work. Anonymously accessed sites will also work. Any SharePoint site that uses authentication will fail however so this is not really a solution..
To solve this would I have to encapsulate all my database access code to run with elevated priviliges, is that how SharePoint does it internally? Somehow that doesn't seem like the most performant solution.
Is that still the way to go, just use SQL security to access databases from SharePoint custom web parts?
The <identity /> and <authentication /> elements in the web.config file will together determine the account that is used in to connect to SQL Server when using integrated authentication.
When <authentication mode="Windows" /> is configured, you're deferring to IIS to authenticate users. I'm guessing that your your web.config contains:
<authentication mode="Windows" />
<identity impersonate="true" />
and that IIS is configured to allow anonymous users. Setting <identity impersonate="true" /> causes IIS to pass the identity of the IIS anonymous access account to SQL Server.
As Lars point out, using SPSecurity.RunWithElevatedPrivileges will achieve what you want. I don't believe you'll see any noticeable impact on performance but that's something you can test :-)
Use SPSecurity.RunWithElevatedPrivileges to run your code in the context of the app pool identity.
This is incorrect. Because <identity impersonate="true" /> is set to true ASP.NET / IIS will run the thread as the user that is currently logged in (so not the app pool account but the actual user logged into the website).
Something else is going on here. Could you post your connection string for the custom database? (minus the private data off course)

Resources