I'm working on a webapplication which runs central at a company. This webapplication needs to make a call to a service which is part of a second webapplication.
In the central webapplication i have this piece of code;
var clientUri = "http://website.localhost/Services/Info.svc/account";
var uri = new Uri(clientUri);
var networkCredentials = new NetworkCredential(_configuration.ServiceUserName, _configuration.ServicePassword);
var httpClient = new HttpClient();
httpClient.DefaultHeaders.Authorization = Credential.CreateBasic(_configuration.ServiceUserName, _configuration.ServicePassword);
httpClient.TransportSettings.PreAuthenticate = true;
HttpResponseMessage respone = httpClient.Get(uri);
HttpContent content = respone.Content;
In the webservice in the other application, which is (Info.svc), i have the following code in the Constructor of the service.
var validator = new UserNamePasswordValidator();
var cred = System.Net.CredentialCache.DefaultCredentials; //this one is empty, maybe a solution?
validator.Validate("Username", "Password");
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
//This throws a 401 unauthorize, which is shown as a 500 error in the central application
throw new WebProtocolException(HttpStatusCode.Unauthorized, "You must be authorized to perform this action.", null);
}
else
{
_userIsAbleToUseService = true;
}
Instead of Username and Password in the validate function i want to use the Network Credentials sent over from the other webservice, can this be achieved? And how? Any other suggestions are welcome! I can harcode the password now in the validate function, but this isn't what i want.
--UPDATE--
This is the configuration in the web.config for the central application
<authorization>
<allow roles="administrators"/>
<deny roles="datareaders"/>
<deny users="?"/>
</authorization>
<authentication mode="Forms">
<forms loginUrl="~/Logon/Logon" timeout="2880"/>
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="CentralApplication"/>
</providers>
</membership>
This part is for the web.config in the second webapplication
<authentication mode="Forms">
<forms name="AllPages" loginUrl="~/Logon/" timeout="360" enableCrossAppRedirects="false" />
</authentication>
<authorization>
<!-- NOTE: See Web.config under Private folder for specifics on secure pages. -->
<deny users="?" />
</authorization>
<membership defaultProvider="NHMembershipProvider">
<providers>
<clear />
<add name="NHMembershipProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsMembershipProvider" description="Stores and retrieves membership data from SQL server using Nhibernate" connectionStringName="NHibernate" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="NHRoleProvider">
<providers>
<clear />
<add name="NHRoleProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsRoleProvider" />
</providers>
</roleManager>
Already being logged to the central application using the membership provider i'm trying to call the webservice from there using a simple hyperlink (just for now). The webservice called in the central admin gathers some data and sends this over to the url for the webservice of the second application. Both application are webapplications (containing webservices) so that is why the authentication mode is set to Forms.
Took me nearly 2 days, but now i got everything working as i want. I found the WcfRestContrib Which allowed me to implement authentication on the services by modifying my webconfig a bit and using a few attributes from this class. I build a quick testapplication with an service and a console application and the authentication worked.
I added the section below to my web.config;
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="webAuthentication" type="WcfRestContrib.ServiceModel.Configuration.WebAuthentication.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
<add name="errorHandler" type="WcfRestContrib.ServiceModel.Configuration.ErrorHandler.BehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
<add name="webErrorHandler" type="WcfRestContrib.ServiceModel.Configuration.WebErrorHandler.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="Rest">
<webAuthentication requireSecureTransport="false" authenticationHandlerType="WcfRestContrib.ServiceModel.Dispatcher.WebBasicAuthenticationHandler, WcfRestContrib" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, CMS.Backend" source="CMS.Backend"/>
<!--<webAuthentication requireSecureTransport="false" authenticationHandlerType="CMS.Backend.Services.WebBasicAuthenticationHandler, CMS.Backend" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, Website.Backend" source="CMS.Backend"/>-->
<errorHandler errorHandlerType="WcfRestContrib.ServiceModel.Web.WebErrorHandler, WcfRestContrib"/>
<webErrorHandler returnRawException="true" logHandlerType="Website.Backend.Services.LogHandler, Website.Backend" unhandledErrorMessage="An error has occured processing your request. Please contact technical support for further assistance."/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
After that i modified my service interface to look like this;
[ServiceContract]
public interface ICmsInfo
{
[OperationContract]
[OperationAuthentication]
[WebInvoke(UriTemplate = "account", Method = "GET")]
AccountDTO GetAccountInfo();
The final step i took was adding 2 attritubes to the service itself;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceConfiguration("Rest", true)]
public class Cmsinfo : ICmsInfo
{
//foo
}
The WcfRestContrib helped me a lot by adding this authentication technique and it works great. I just had to make sure i used the authorization headers aswell.
After this i ran into a problem while authenticating the webservice in my webapplication which is using Forms Authentication. This problem is specified in another topic.
Related
Where’s my auth cookie gone?
When redirecting from my SSO to a client application, the .ASPXAUTH cookie is lost but only if the two sites are not on the same server.
In Fiddler, I can see the cookie being set by the SSO to the Response, in the correct cookie path for the client app. Upon redirecting however, I see that the request does not bear the cookie.
Response after logging into SSO:
Request back to client application:
Relevant sections of the Login apps web.config:
<machineKey compatibilityMode="Framework20SP2"
decryption="AES"
decryptionKey="<a valid RSA key>"
validation="SHA1"
validationKey="<a valid HMACSHA256 hash>"
/>
<!-- "SHA1" actually implements HMACSHA256, but for one reason or another, we can't specify it explicitly. -->
<authentication mode="Forms">
<forms loginUrl="Index"
cookieless="UseCookies"
requireSSL="false"
name=".ASPXAUTH"
path="/path/to/SSO-Virtual-Directory/"
slidingExpiration="true"
timeout="20"
enableCrossAppRedirects="true"
protection="All"
ticketCompatibilityMode="Framework20"
/>
<!-- set cookie path relative to virtual path of the application in IIS. See Application -> Advanced Settings to see the virtual path.
Cookie Paths, Domains, and Names are all CASE SENSITIVE!!!!!
Be sure to check the virtual path, as it doesn't update when you rename path tokens to change case. you will have to recreate the application to update the virtualpath-->
</authentication>
<!--SSOConfig Providers-->
<membership defaultProvider="SqlMembershipProvider" >
<providers>
<clear />
<add name="ADMembershipProvider"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName"
enableSearchMethods="false"
connectionUsername="<a valid domain username"
connectionPassword="<a valid password>"
type="System.Web.Security.ActiveDirectoryMembershipProvider"
/>
<!-- do not set applicationName= .-->
<add name="SqlMembershipProvider"
connectionStringName="SqlConnectionString"
applicationName="SSO"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true"
passwordFormat="Hashed"
minRequiredNonalphanumericCharacters="0"
type="System.Web.Security.SqlMembershipProvider"
/>
<!-- for some messed up reason applicationName is required.-->
</providers>
</membership>
<roleManager defaultProvider="SqlRoleProvider"
enabled="true"
cacheRolesInCookie="true"
cookieName=".ASPROLES"
cookieTimeout="30"
cookiePath="/path/to/Virtual-Directory/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="All"
>
<!--set cookie path relative to virtual path of the application in IIS. See Application -> Advanced Settings to see the virtual path. eg: /secure/sso/CentralLogin/ on Exodus.
Cookie Paths, Domains, and Names are all CASE SENSITIVE!!!!!
Be sure to check the virtual path, as it doesn't update when you rename path tokens to change case. you will have to recreate the application to update the virtualpath-->
<providers>
<clear />
<add name="SqlRoleProvider"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="SqlConnectionString"
applicationName="SSO"
/>
<!-- set ApplicationName-->
</providers>
</roleManager>
Client Web.config:
<machineKey compatibilityMode="Framework20SP2"
decryptionKey="<The same RSA key>"
validation="SHA1"
validationKey="<The same HMACSHA256 hash>"
/>
<authentication mode="Forms" >
<forms loginUrl="~/login/Index"
name=".ASPXAUTH"
path="/Payment/"
requireSSL="false"
slidingExpiration="true"
timeout="20"
cookieless="UseCookies"
enableCrossAppRedirects="true"
protection="All"
ticketCompatibilityMode="Framework20"
/>
</authentication>
<membership defaultProvider="SqlMembershipProvider" >
<providers>
<clear />
<add name="ADMembershipProvider"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName"
enableSearchMethods="true"
connectionUsername="<a valid domain username"
connectionPassword="<a valid password>"
type="System.Web.Security.ActiveDirectoryMembershipProvider"
/>
<add name="SqlMembershipProvider"
connectionStringName="SqlSSOConnection"
applicationName="SSO"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true"
passwordFormat="Hashed"
minRequiredNonalphanumericCharacters="0"
type="System.Web.Security.SqlMembershipProvider"
/>
</providers>
</membership>
<roleManager defaultProvider="SqlRoleProvider"
enabled="true"
cacheRolesInCookie="true"
cookieName=".ASPROLES"
cookieTimeout="30"
cookiePath="/Payment/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="All"
>
<providers>
<clear />
<add name="SqlRoleProvider"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="SqlSSOConnection"
applicationName="SSO"
/>
</providers>
</roleManager>
Both sites are MVC5 on .Net 4.5.2.
Does anyone have any ideas as to whats going wrong, and what I can do about it?
So as we seems to found out in comments, the problem is SSO and client reside on different domains\ips and so cookie set for SSO will not be passed to client by browser. There are different ways to solve this, but they require change of how your general SSO process works.
As I understand you only have problem with that in development environment, not on production. If so, suppose your SSO is on 10.0.0.1 and your client is on 127.0.0.1. Then map client.yoursite.local domain (in your corporate DNS or just in /etc/hosts file) to 127.0.0.1 and yoursite.local to 10.0.0.1, and use domain names instead of raw ip addresses. Then in SSO set cookie with domain of ".yoursite.local". This then should be delivered correctly to your client application, and will not require significant changes to how your SSO process works.
EDIT: Can anyone explain why I am getting "/" for the username? See my "Answer" below
I created a new WebForms application in VS2013 (.NET 4.51) which included the "new" Identity membership provider. I wanted to use the older Membership provider so did as follows.
Populated the necessary entries in web.config as follows:
:
<membership defaultProvider="DefaultMembershipProvider">
<providers><add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
and
<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<roleManager defaultProvider="DefaultRoleProvider" enabled="true">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
I doubled checked the authentication node:
<authentication mode="Forms">
<forms loginUrl="Account/Login" timeout="120" defaultUrl="/">
</forms>
</authentication>
My login code is as follows:
if (Membership.ValidateUser(txtUserName.Text, txtPassword.Text))
{
FormsAuthentication.RedirectFromLoginPage("/", chkRememberMe.Checked);
}
and my logout code:
FormsAuthentication.SignOut();
Session.Abandon();
FormsAuthentication.RedirectToLoginPage();
however HttpContext.Current.User.Identity.IsAuthenticated always returns TRUE, which means that even after I logout I can access any page in the site even through I have the following restriction:
<!-- Entire site is secured -->
<location path=".">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
What am I missing here? I am guessing there is still some legacy from the original Identity provider which I have not eradicated which is causing this issue. At this point security is not working at all for me and I need to get it working without using the new Identity membership provider which is the default for new applications generated via the new application template in VS2013.
All pointers and suggestions greatly appreciated.
I came back to this today and now pages are authenticating as expected (WT....). So I am guessing that there must have been a cookie somewhere that was not being cleared. However something is still not right.
Once the user has authenticated when I inspect:
System.Web.HttpContext.Current.User.Identity.Name
I am getting:
"/"
as the result instead of the name the user entered when they logged in via:
Membership.ValidateUser(txtUserName.Text, txtPassword.Text)
ie. why am I not getting the value of txtUserName.Text instead of /
I guess a related question is, is there a HOWTO on how to revert a project from Identity to the previous Membership system?
This is probably a noob question, I am new to ASP.NET Login controls. The problem is, the login page loads and you enter the username and password. However, it always says "Your login attempt was not successful. Please try again." That prompted me to see if it was even hitting the db. It is not, because this is the connection string as you can see below:
connectionString="Data2121212 Source=20e2127213597;Initial Catalog=ramsl323312sanddb;User Id=ramsl1342anddb42o;Password=r13zzzzzzbs;"
Even with that connection string which is completely invalid it throws no error. So obviously its not even trying to connect. What I can't figure out, is why is not connecting. I was told that the login control would just read the web.config file and pick up the connection string etc. But its not. Can someone please explain to me whats going on?
And yes, the site is using that config file.
<connectionStrings>
<clear/>
<add name="LocalSqlServer" connectionString="Data2121212 Source=20e2127213597;Initial Catalog=ramsl323312sanddb;User Id=ramsl1342anddb42o;Password=r134zAP5bs;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies></compilation>
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="~/Login.aspx"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<!-- Validation and decryption keys must exactly match and cannot
be set to "AutoGenerate". The validation and decryption
algorithms must also be the same. -->
<machineKey validationKey="AB5D0FE7450DA6CB8821D213C36EE85BC26FB34259E194B86F2D7240D10B42AE8887A5204B733EF7E860963C0403CA12FBF0892AD50570B4E79D5DC530FD1CFF" decryptionKey="1ED07D110F095B571EB62B0EF4C6D6F4F2DA5596103C233E98C8B6832C23F888" validation="AES" decryption="AES" />
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear/>
<add connectionStringName="LocalSQLServer" applicationName="/" enablePasswordRetrieval="true" passwordFormat="Encrypted" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider"/>
</providers>
</membership>
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear/>
<add connectionStringName="LocalSQLServer" applicationName="/" name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
<providers>
<clear/>
<add connectionStringName="LocalSQLServer" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Try putting the following line in:
So your new connection strings settings should look like this:
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data2121212 Source=20e2127213597;Initial Catalog=ramsl323312sanddb;User Id=ramsl1342anddb42o;Password=r13zzzzzzbs;"/>
</connectionStrings>
now for as long as your Database has the ASP.Net database in it with a user account it should work perfectly fine.
I got it! My noob client coded the login control all wrong apparently, because when I used a new one, it worked great!
Also, great tips here for anyone who has an issue like this:
http://www.codeproject.com/Articles/27682/Your-Login-Attempt-was-not-Successful-Please-Try
I've implemented a challenge-response scheme as an Ajax handler.
For some reason it stopped working after working fine for a couple months.
Investigating the issue showed that Context.Session[KEY] had lost its value between the challenge and the response calls.
I put Session_Start and Session_End (and a few other) methods in Global.asax.cs with some logging there and I see a new Session_Start event being fired with the same session ID and there was no Session_End event
Question is: why does IIS lose the session values?
Update: I tried switching to SQLServer sessions but there was no change in behavior. On rare occasions sessions work as intended, not sure why. I tried all "session losing variables" troubleshooting guides I could find to no effect
UPDATE 2: I narrowed down the issue to a missing session cookie, but modifying my.browsers config didn't resolve the issue after several attempts. When I call the ajax handler from a browser the session cookie "ASP.NetSessionId" shows up as expected. I changed the cookie name in IIS settings for both the site and the server to "SessionId" but I kept seeing ASP.NET, even after restarting the server. I would still like to give the bounty to someone who has an idea what's going on. In the meanwhile I worked around this problem by setting a session cookie in code.
Pseudo code for Login.ashx:
string login = GetParameter("login", context);
string passhash = GetParameter("pass", context);
string challenge = "" + Context.Session["CHALLENGE"];
if (!string.IsNullOrEmpty(challenge))
{
// this is the 'response' part
string challengeResponse = Crypto.GetChallengeResponse(Challenge, UserFromDB.PassHash);
if (challengeResponse == passhash)
{
// Great success, challenge matches the response
Log.I("Success");
return "SUCCESS";
}
else
{
Log.W("Failed to respond");
return "FAILED TO RESPOND";
}
}
else
{
// if passed login or session-stored challenge are empty - issue a new challenge
challenge = "Challenge: "+ Crypto.GetRandomToken();
Context.Session["CHALLENGE"] = challenge;
Log.I("Sent Challenge"); // this is what's in the log below
return challenge;
}
Here's the log, Session started appears with each call, Session.Keys.Count stays 0 even though Session["CHALLENGE"] should have been set:
// This is the challenge request:
[] **Session started**: sr4m4o11tckwc21kjryxp22i Keys: 0 AppDomain: /LM/W3SVC/1/ROOT-4-130081332618313933 #44
[] Processing: <sv> **MYWEBSITE/ajax/Login.ashx** SID=sr4m4o11tckwc21kjryxp22i
[] Sent Challenge #Login.ashx.cs-80
// this is the response, note that there's another Session started with the same id
// and the session didn't keep the value ["CHALLENGE"], there are no session-end events either
[] **Session started**: sr4m4o11tckwc21kjryxp22i Keys: 0 AppDomain: /LM/W3SVC/1/ROOT-4-130081332625333945 #93
[] Processing: <sv> **MYWEBSITE/ajax/Login.ashx?login=MYLOGIN&pass=RuhQr1vjKg_CDFw3JoSYTsiW0V0L9K6k6==**
[] Sent Challenge #Login.ashx.cs-80 >Session: sr4m4o11tckwc21kjryxp22i
web config, sanitized
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="IncludeStackTraceInErrors" value="false" />
</appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
<add name="MYConnection" connectionString="metadata=res://*…. and a bunch of other stuff that works" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation targetFramework="4.5">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<pages controlRenderingCompatibilityVersion="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>
What is the default value for Idle Time-out ? If the app pool times out your session goes bye bye
See Application Pool (Advanced Settings) -> Idle Time-out
I think it defaults to five minutes.
See this link for advice on setting the idle timeout
You could also experience your issue if your running as a webgarden when it's not needed; look at Maximum Worker Processes, try setting it to 1 and retest
I can see you are using handler for that purpose which would always return null.
You need to implement IReadOnlySessionState.
Check out http://www.hanselman.com/blog/GettingSessionStateInHttpHandlersASHXFiles.aspx
Add IRequiresSessionState to your handler implimentation
ex
public class handler_name:IHttpHandler, IRequiresSessionState
Forms Authentication does not work. Auth cookies are not sent to server when SMF attempts to get access to *.ism/Manifest files on a server that requires specific user roles.
What i do:
1. Create new Silverlight Smooth Streaming template with supporting RIA WCF.
2. Configure web.config :
<connectionStrings>
<add name="ApplicationServices" connectionString="Data Source=[SERVER];Initial Catalog=[CATALOG];User ID=[USER];Pwd=[PASSWORD];" providerName="System.Data.SqlClient" />
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
<properties>
<add name="Gender" />
<add name="Birthday" />
<add name="AvatarPath" />
</properties>
</profile>
<roleManager enabled="true">
<providers>
<clear />
<add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
</providers>
</roleManager>
Add Authentification Service and correct User class (add 3 props).
On client side add this to app.xaml.cs:
public App()
{
//Default things...
InitializeWebContext();
}
private void InitializeWebContext()
{
WebContext webContext = new WebContext();
var fa = new FormsAuthentication();
var ac = new AuthenticationDomainService1();
fa.DomainContext = ac;
fa.Login(new LoginParameters("user", "password"), (y) =>
{
if (!y.HasError)
{
this.RootVisual = new MainPage();
}
}, null);
webContext.Authentication = fa;
ApplicationLifetimeObjects.Add(webContext);
Resources.Add("WebContext", WebContext.Current);
}
Access is restricted by web.config file in target directory:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<authorization>
<allow roles="Role_name" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
User exists in this role.
When I use the default video that's specified in Xaml (Big Bunny) - everything is fine. But when I change mediasource to a path to s restricted zone on my server I get an access error.
On the client side, I get user credentials succesfully.
Fiddler shows next thing:
When I try access to another resctricted methods ([RequiresAuthentication]) on RIA WCF, client send Auth cookies, but when SMFPlayer try access to media source, that cookie wasn`t sent.
What have I missed?
I found some workaround:
If you transfer the stream files into a subdirectory, and restrict access to it (instead of a directory with "ism" files). Manifest will be issued to anonymous users, but the data streams is only for registered (when player try touch data stream it sucessfully attach auth cookies).