ClaimsPrincipal.Current vs. HttpContext.Current.User? - asp.net-mvc

In MVC what's the difference between these 2?
They look identical, and they even return the same Type/Class System.Web.Security.RolePrincipal but there're subtleties.
Eg. The following code throws various errors when called against the instance generated via ClaimsPrincipal.Current
cp.FindFirst(ClaimTypes.Name); //{"Unable to connect to SQL Server database."} <--HUH!?
cp.Claims; //{"Value cannot be null.\r\nParameter name: username"}
The above works when cp is this instead:
var cp = System.Web.HttpContext.Current.User
When drilling down to the private members via quick watch I can see that they both has the same Claim dictionary. However for whatever reason the public property blows when called against the object returned by ClaimsPrincipal.Current
Help - why is this!? This is driving me crazy.
=============EDIT==================
It must be almost time to go to bed.
IPrincipal supports multiple identities. It requires some kind of store.
IIdentity returns an instance of ClaimsIdentity and does not require the store.
I was simply drilling the wrong properties. The two of them are almost identical in their shape ie. same properties and methods, that I got them confused.

The Identity is the current authenticated user and the principal is the security context that the code is running under.
This article is a good explanation that I found useful http://msdn.microsoft.com/en-us/library/ftx85f8x.aspx .

Related

OData Model not loaded?

I am using an OData model in my SAP UI5 application. I do the following:
var oView = this.getView();
this._oModel = oView.getModel();
which I thought loaded the model and allowed me to access whatever I needed to inside the model. However whenever I try to get a property using getProperty(path) it returns undefined. I know the path is correct because I used it elsewhere in my application and it worked okay. The model I am using is named "metadata.xml" if that helps.
If you read the documentation provided by SAP talking about OData services (I assume v2), you might find your answer there. Since you are using getProperty(), "you can only access single entities and properties with these methods. To access entity sets, you can get the binding contexts of all read entities via a list binding." Therefore you may want to a read() of the entity set first and then use the results of this read to access whatever property you want.
Link to doc: https://sapui5.hana.ondemand.com/#docs/guide/6c47b2b39db9404582994070ec3d57a2.html

Custom UserSessionRegistry in Spring web socket implementation for a multi tenant scenario?

I am working with Spring Websocket (4.1.4 release) and using #SendToUser for sending messages to the current user. But I've a problem. Ours is a multi-tenant platform where username is not unique, instead a combination of username and tenant id is unique. The DefaultUserSessionRegistry keeps a map from username to a list of session ids:
private final ConcurrentMap<String, Set<String>> userSessionIds = new ConcurrentHashMap<String, Set<String>>();
which would not work in my scenario. So is there a way I can plugin my custom UserSessionRegistry implementation?
After a code search, the issue seems related to this line.
I found that this class is extended by WebSocketMessageBrokerConfigurationSupport, which is extended by a #Configuration class (DelegatingWebSocketMessageBrokerConfiguration), so you could try to extend it by yourself, like in this example:
https://github.com/arawn/overview-of-spring4/blob/master/src/main/java/jco/conference/oxquiz/WebSocketConfig.java
I had no time to verify this, but if your problem is only the UserSessionRegistry implementation, this could be the way of overriding that #Bean method.
Update:
After digging a bit more, I found the real entry point to the whole flow: search for the DefaultHandshakeHandler class, having the determineUser method (I cannot add more links because of my low score)

Error when adding to many-to-many table in EF6

I have recently changed from ObjectContext to DbContext using EntityFramwework by upgrading to EF6
Most stuff works, but saving and updating won't. Here is an example:
public void AssignToAdmin(Product product, Admin admin)
{
var pcsps = from s in context.ProductCreationSections
join pcsp in context.ProductCreationSectionAndProducts on s.ProductCreationSecitionID equals pcsp.ProductCreationSectionID
where pcsp.ProductID == product.ProductID && s.IsManagerAssigned
select pcsp;
foreach (var pcsp in pcsps.Include("AssignedAdmins"))
{
pcsp.AssignedAdmins.Add(admin);
}
}
Trying to execute the line pcsp.AssignedAdmins.Add(admin), I get the error:
Error: The relationship between the two objects cannot be defined
because they are attached to different ObjectContext objects.
There is one context for the class and it comes from Dependency Injection (the class is a Service in an MVC app).
I've tried removing/attaching and so on, but this doesn't fix it - it just gives different error messages. It's not even obvious which entity is using another context.
Any ideas of where this other context the error message refers to is coming from?
See The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects
Where has admin come from?
Getting the admin object from the same context as the pcsp object should help.
Sorted it, but it was quite a major refactor.
The issue was that each service received it's own instance of 'context', so when two entities from two services were expected to work together, they wouldn't as each belonged to a different context.
One solution would have been to make the class that created the context a 'Singleton' so that it always returned the same instance, but that would have been very BAD as every page would then use the same context.
Each service got it's own instance of 'context' through Dependency Injection.
I changed the project so only the controllers got an instance of context through DI. Then, in the controller constructor, this context was passed to the services that the controller had received through dependency injection.
This way, each request only ever uses a single instance of context, but this instance is still short lived, as it is supposed to be as each request has its own context and doesn't share one.
Not sure this is the way it is supposed to work, but given the web app I was working with, this seemed to be the best solution.
I also had to go through and add a 'context.SaveChanges();' statement everywhere a change to the database was made.
Not sure why this should be when the old version of EF did this automatically, but it now works.
Thanks for the advice Derrick

Business Logic + ASP.NET MVC

I've an MVC application, which is divided into 3 layers:
- Presentation - ASp.NET MVC
- Busines Logic - Here we have entities and object services. We alo have mappers between DAL objects and BL objects
- Data Access Layer - we use EF to query the database.
Now, we've created a factory for object services, and the factory is injected into presentation later using Unity. Each time I want to do some logic, I call an appropriate service which uses DAL repositories to do some stuff.
Now, silly question, let suppose that I want to check if I can add a user with a provided nickname. The nickname is unique in the database, so before I add the user, I check if a user with provided nickname exists. So, it's a simple query that returns true/false. Becuase I don't have any connections between presentation layer and business layer, I check it in the service. But the code of the service method simply looks like:
var exists = repository.NicknameExists(nickname);
return exists;
The code above is strange, because it does nothing, just calls a method and returns its value. On the other hand, I've Separation of Concerns, so my solution is well organised. Can someone give me some suggestions, how should I solve problems like that?
I don't see any problem here. It's perfect method for me:
public bool IsUserExists(string nickname)
{
return repository.NicknameExists(nickname);
}
I would recomend to you to read this blog post about valid reasons to create a routine or the chapter 7.1 of the Code Complete 2ed

Strange Caching issue with ASP.NET MVC using Linq

Using asp.net MVC in c#, I am making a call to a stored procedure using Linq into my SQL Members table. I have no internal caching on the application, already checked to make sure it is turned off.
Test case:
I have my username set to test1. From the website I change my username to test2. The website still shows test1. I go to Management Studio and run my stored procedure called MemberByEmail, it shows test2 correctly.
I start simple, refresh my page to see if it's browser cache, still test1. I go to debugging and walk through the code and find that it goes correctly all the way to here to call the database:
/// <summary>Method that is mapped to the dbo.MemberByEmail database procedure.</summary>
/// <returns></returns>
[System.Data.Linq.Mapping.Function(Name="dbo.MemberByEmail")]
public System.Data.Linq.ISingleResult<BookCrossing.Data.Member> MemberByEmail(
[System.Data.Linq.Mapping.Parameter(DbType="nvarchar(100)")] string email)
{
var methodInfo = (System.Reflection.MethodInfo)System.Reflection.MethodInfo.GetCurrentMethod();
var result = this.ExecuteMethodCall(this, methodInfo, email);
return ((System.Data.Linq.ISingleResult<BookCrossing.Data.Member>)(result.ReturnValue));
}
I turned on the profiler for my sql db, and it actually shows an entry for MemberByEmail, and the result set that came back had username = test1 .
Again I ran the stored procedure through Management Studio, and it came up with test2 as the username. I waited for 15 minutes, refreshing the web page every 5 or so, and it never cleared and served the correct test2 from the db. The last strange piece, I ran IISReset and refreshed the page, test2 was returned.
I'm guessing this I am just overlooking something obvious. Any help or advice would be great. Thanks
UPDATE: I created a console application to take out the web piece of it. The problem is the same when accessing directly from a console app also, no change.
How are you calling this from the webpage? If via an Ajax call, IE helpfully caches the result for you...
Took a while but we got this resolved. Data access is done through a MemberRepository in our project, and we loaded member repository in our MembershipProvider class. The problem is that the MembershipProvider class was loaded at the start of the application and never removed, so all MemberRepository calls were done through the same context. The strange part is that the call went all the way to SQL (as noted we were able to see the request in profiler), but the bowels of the code got back the results set but instead used the first calls result set and sent that back to us.
So by moving the Repository into the desired method or our MembershipProvider, it was destroyed after each call and that solved the issue. I don't know that this is specific to our set up, but hopefully it will help someone in the future.

Resources