HttpContext.Current.Session gets cleared on routing in Azure Server - asp.net-mvc

public static WebUser LoggedUser
{
get
{
WebUser sessionValue = null;
if (HttpContext.Current.Session["LoggedUser"] != null)
{
sessionValue = (WebUser)HttpContext.Current.Session["LoggedUser"];
}
return sessionValue;
}
set
{
HttpContext.Current.Session["LoggedUser"] = value;
}
}
HttpContext.Current.Session gets cleared on routing in Azure Server, the same works fine in IIS server but why not in Azure??
Please help me in persisting session value

HttpContext.Current.Session gets cleared on routing in Azure Server, the same works fine in IIS server but why not in Azure??
I assume that you use the multiple instances Azure WebApp. If it is that case, we could get the answer from the azure official document. Please have a try use external session state provider (either the Redis Cache Service or a SQL Server session state provider).
If your ASP.NET web app uses session state, you will need to configure an external session state provider (either the Redis Cache Service or a SQL Server session state provider). If you use session state, and don't use an external provider, you will be limited to one instance of your web app.

Related

oauth 2.0 - Resource owner password flow, can use windows login user credentials

I am using Identity Server 3 and using InMemoryUsers to keep my user/password info,
factory.UseInMemoryUsers(Users.Get());
For one of my client I'am using ResourceOwner password flow,
Flow = Flows.ResourceOwner,
Now, I am able to get access token by below setting, sending user/pass which we store In-Memory,
Now question is,
can I use windows local users credential in place of in-memory users?
There's a service called IUserService which is responsible for getting user and its profile.
When you are using InMemory Users in fact you are using InMemoryUserService.
If you want to use windows local users, you need to implement your own IUserService and get users from windows and then register your service.
public CustomUserService : UserServiceBase
{
public override Task AuthenticateLocalAsync(LocalAuthenticationContext context)
{
// You need to implement `GetUserFromWindows` to get users from windows local
var user = GetUserFromWindows(context.UserName, context.Password);
if (user != null)
{
context.AuthenticateResult = new AuthenticateResult(user.Subject, userDisplayName);
}
return Task.FromResult(0);
}
}
factory.UserService = new Registration<IUserService, CustomUserService>();

identity server load balancing logout issue

i am working on identity server 4 with .net core micro service architecture, i have followed this reference application please click Here.i have also used docker container to deploy distributed approach application.its working fine when it is in development i.e local environment.
but on production i am using Load balancing on identity server, because of load balancing i am facing log out issue.
Ex . i have created 3 instances of Identity server for production purposes i.e A,B and C, based on user load it will automatically switch between instances.Now the problem is when user logged in A instances after few seconds it automatically requests to B or C instances because of load balancing, so problem is user logged in A instance and current request is handled by B or C instance so how server will know that user is logged in or not,that's why its logging out me and redirects to log in screen.
EDIT :
Please check with Identity server configuration and operational store with signin certificate
I believe the issue you have is due to the data protection in asp.net core, each container will be using different keys to encrypt / decrypt data. To verify just run one instance of the container, if this resolves your problem then look at : https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/
public class XmlToDbRepository : IXmlRepository
{
private readonly IPersistKeyDb _persistKeyDb;
public XmlToDbRepository(IPersistKeyDb persistKeyDb)
{
_persistKeyDb = persistKeyDb;
}
public IReadOnlyCollection<XElement> GetAllElements()
{
return _persistKeyDb.GetAll().Select(i => XElement.Parse(i.Key)).ToList().AsReadOnly();
}
public void StoreElement(XElement element, string friendlyName)
{
_persistKeyDb.Store(friendlyName,element.ToString(SaveOptions.None));
}
}
I think this is the one you'll be interested in.

IdentityServer3 - redirect to ADFS if client is on intranet

We have a portal (mvc rdp) that is used by both internal users (employees) and external users (customers). We would like IdentityServer3 to automatically detect if the authentication request is done from within the corporate network, and redirect to ADFS. The local login should be shown if the user-agent is calling from the internet.
In short, we don't want to have buttons for the external idp as we want the IdSrv to automatically redirect to ADFS if client is on the internal network to provide true single sign on for our domain bound users.
If the portal was only used by internal users, then we would just configure the client to only use a particular identity provider but this portal is also used by external customers and those users are not stored in our AD ;)
I've looked at overriding PreAuthenticateAsync and using Dns.Dns.GetHostName() but that is related to the machine that IdentityServer is running on and not the client machine.
In an mvc controller, we would just use Request.UserHostName but this is not available in IdentityServer3 UserService.
I think you can get the client's IP address from the OwinContext; something like this:
public class UserService : UserServiceBase
{
OwinContext ctx;
public UserService(OwinEnvironmentService owinEnv)
{
ctx = new OwinContext(owinEnv.Environment);
}
public override Task PreAuthenticateAsync(PreAuthenticationContext context)
{
// The IP Address of the remote client
var ipAddress = ctx.Environment["server.RemoteIpAddress"].ToString();
if (BelongsToOurNetwork(ipAddress))
context.SignInMessage.IdP = "OurADFS";
else
context.SignInMessage.IdP = "idsrv"; // local login
return Task.FromResult(0);
}
}

Session without authentication with MemoryCacheClient in servicestack with MVC4

i am new to Servicestack. I am having MVC4 application and servicestack application deployed on diffrent servers .
I want to use the servicestack session without authentication with MemoryCacheClient.
i am not able to understand the explanation given in
https://github.com/ServiceStack/ServiceStack/wiki/Sessions
I want to check if session is there for each request and if seesion is null create new session with custom value as user id.
My configure method is as followes
public override void Configure(Container container)
{
// in global request filter check if session exists
this.GlobalRequestFilters.Add((req, res, requestDto) =>
{
//check if session exists
var sessionId = req.GetSessionId();
if (sessionId == null)
{
//if no populate session with user defined data ( user id from requestDto)
}
else
{
//how to get the values from session ?
}
}
Please help .
Thanks in advance
The SessionFeature already registers their own Global Request Filter to automatically create missing Temporary or Permanent Session Ids (i.e. ss-id or ss-pid).
It sounds like you want to register a Custom AuthEvent to respond to different events in the session lifecycle, i.e. IAuthEvents.OnCreated().

Keeping User Information in Session in MVC is not Secure

I had a Posting on a blog about Sessions AND Cookies. Here are details
Sessions
Sessions are More Secure
Sessions are on the server
Cookies
Cookies are On client side
Less Secure
Once it is disable on browser the difficult to use.
On the basis of above argument i used sessions in Login system to keep UserId,UserName & roleName
Now on the the basis of roleName i will decide either this is Admin to enter to administrator section or not.
I have used this Code in Model in MVC
public bool LoginMe()
{
Int64 Error;
//create db
Database db = DatabaseFactory.CreateDatabase("DBContext");
DbCommand dbCommand = db.GetStoredProcCommand("ValidateUser");
db.AddInParameter(dbCommand, "#Username", DbType.String, this.UserName);
db.AddInParameter(dbCommand, "#Password", DbType.String, EncryptPassword(this.Password));
db.AddOutParameter(dbCommand, "#Error", DbType.Int64, 10);
DataSet dsResult = db.ExecuteDataSet(dbCommand);
Error = Convert.ToInt64(db.GetParameterValue(dbCommand, "#Error"));
if (Error == 1100)
{
try
{
var query = (from o in dsResult.Tables[0].AsEnumerable()
select new AllUser
{
UserId = o.Field<int>("UserId"),
UserName = o.Field<string>("UserName"),
roleName = o.Field<string>("roleName"),
}).Single(); // this will raise an exception if there isn't just one record returned
Session["UserId"] = query.UserId;
Session["UserName"] = query.UserName;
Session["roleName"] = query.roleName;
return true;
}
catch {
// do nothing and let method return false as something has gone wrong.
// add logging here if you are using it to show there has been a problem
}
}
return false;
}
I used it in View like #Session["UserId"]
Now an expert comment on this like
If you aren't using https and securing the session cookie then this might make it easy to hack your site, although that's the same for any session based site (nearly all of them)
It might be nice to add some check so that if you remove a user's rights, the session variables are deleted the next time that user requests something from the server,
otherwise they could carry on using the site even though their account it banned.You'd have to decide if this is likely and then how you want to do this (using an authorization filter maybe.)
Above comments confused me.Can any body make it clear?What is the best way to keep these information?
Session state uses client tickets to identify the server-side session, it may be susceptible to session ID spoofing and injection attacks.
So, to hack session values one would require hacking the remote-server.
And yes, for highly secure application(such as online banking) use https.
http://msdn.microsoft.com/en-us/magazine/cc163730.aspx#S9
Secure sockets layer (SSL) should be used to prevent network-level sniffing of session IDs, authentication tickets, application cookies, and other request/response information.
Can session value be hacked?
Use HTTPS if you application handles sensitive information(credit-card number,account num,passwords).
Store the User object (model with userId,username,role) in the session than separate attributes
Set setHttpOnly attribute for SESSION_ID.
It might be costly to refresh the User object stored in session before invoking every operation to reflect the current rights stored in database.

Resources