Coder Social home page Coder Social logo

Comments (15)

Nuschler avatar Nuschler commented on July 20, 2024 1

In the SignIn method, after this code...

// create principal/identity
var id = new ClaimsIdentity(claims, method);
var cp = new ClaimsPrincipal(id);

add this...

HttpContext.Current.User = cp;
Thread.CurrentPrincipal = cp;

Otherwise,

System.Security.Claims.ClaimsPrincipal.Current 

is referring to the ClaimsPrincipal created from cookie on initial request.

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

This is because the info for authentication is in the cookie, not in the DB. You need to reissue the cookie -- see the sample code that allows the user to change the gender.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

The following code demonstrates the problem... if the claim is updated via ajax it doesn't actually update until the next full page request.

private function UpdateGender(string newGender)
{
    account.RemoveClaim(ClaimTypes.Gender);
    account.AddClaim(ClaimTypes.Gender, newGender);
    userAccountService.Update(account);

    // since we've changed the claims, we need to re-issue the cookie that
    // contains the claims.
    authSvc.SignIn(User.Identity.Name);
}

[HttpPost]
public JsonResult function myAjaxMethod(){
    UpdateGender("male");

    string gender = System.Security.Claims.ClaimsPrincipal.Current.Claims.GetValue(ClaimTypes.Gender);

    // the "gender" variable will never be "male" in this request (unless it was already male)
    // because although we've set the cookie it hasn't updated the claim until the next request 
    // when it reads the cookie again.
    return Json(gender);
}

Since it is possible to set cookies on the response to any HTTP request, including those made via ajax (http://stackoverflow.com/questions/3340797/can-an-ajax-response-set-a-cookie) I'm a little confused as to why this would be a problem.

Additionally, why can I not get the value I just set for a claim later in my code execution using System.Security.Claims.ClaimsPrincipal.Current.Claims.GetValue()? Surely when setting this should be updated immediately?

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

This issue is beyond the scope of MembershipReboot. MR uses the SAM to issue a cookie that contains the claims so the server-side knows the user's identity. If you want your JavaScript code to know the claims then it's up to you to architect that. And then on top of that if you change those claims in the DB it'd be up to your app to keep the in-memory JavaScript state in sync.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

That's what I mean. Shouldn't the current claimsprinciple be recreated when we resend the cookie instead of waiting for the next request?
so when calling authSvc.SignIn(User.Identity.Name) it should do what you describe automatically?

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

You can do for that, @hades200082, but it's now how the plumbing has ever worked in ASP.NET.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

Yes, I just came across the same issue in a knockout/ajax based app that uses MembershipProvider ... a most illogical way to do it imho.

It would make more sense that after I've just updated the claim I can then retrieve the claim from the system and get the value I just set rather than having to wait for the next request.

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

It's a tricky thing. For example, say it's an authentication request from an anonymous user. What should the server logs say? Was the request authenticated or not? Also, it seems perhaps odd if the identity coming in is not the same as the identity going out.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024
authSvc.SignIn(User.Identity.Name);

This method should update the ClaimsPrincipal.Current. If we've just signed them in then they are now the current signed in identity & claims from that point onwards.

I may be missing something obvious here but I just think that once we've chosen to sign them in the claims in memory should be updated so that they can be reliably accessed in other methods and get the correct data for the newly signed in user.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

http://stackoverflow.com/questions/17095246/system-security-claims-claimsprincipal-not-updating/17103019?noredirect=1#17103019

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

Right -- this is what i meant when i said the identity coming in isn't the same as the identity going out. it's ok to do this, it's just that you need to be aware of this sort of side effect.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

I'm still not sure what side effect you're referring to.

If I'm writing code and I have a request that updates some claims first, then goes on to do other stuff... I would want that other stuff to know what the new claims are, not what they were. What they were is no longer relevant to the currently executing request.

IMHO this is a flaw currently and caused me a lot of confusion as it didn't behave as I would have expected (i.e. once I've updated something for it to actually be updated later in the code, not reverted back to it's previous value)

Is there some gotcha that I'm missing here?

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

Imagine you have some logs that are written before and after the request. In the before log it says alice made the request but in the after log you see bob. This is the sort of issue I meant -- one identity on the way in and another on the way out. Now, you can make the code do anything you want, as long as you understand these subtleties.

Also, what if the current ClaimsPrincipal is not the same as the UserAccount being updated?

As for "fixing" this in MembershipReboot, I don't plan on changing the current behavior. For one, the behavior is consistent with the rest of .NET and ASP.NET. Moreover, I see this as the responsibility of the hosting app. Only your app knows when you're changing the account info and thus would know that it need/wants to reissue the cookie. That's why the sample app does exactly this in the code where the user's claims are changed.

You're free to fork and change the code to work any way you want.

from brockallen.membershipreboot.

hades200082 avatar hades200082 commented on July 20, 2024

I understand now... profile fields are claims just like the identity fields ... I guess it would have to have a custom claim type for profile fields on a per app basis to make sure that it only did this for non-identity claims?

from brockallen.membershipreboot.

brockallen avatar brockallen commented on July 20, 2024

Well, the behavior is whatever you want it to be for your app. It just depends app by app what you want.

from brockallen.membershipreboot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.