Post jest bardziej ku mojej pamięci ale może się to komuś kiedyś przydać :)

Dla jednej z aplikacji musiałem zrobić obejście by programiści mogli testować aplikację nie logując się do niej a jedynie wykorzystując fakowego użytkownika. Jest to spowodowane tym, że środowisko na którym stoi Federation Service nie jest dostępne bez podwójego VPNa. Do tego też każdy z nas pracuje na własnej bazie danych a nie bazie do której FS jest podpięty – więc rejestracja użytkownika, zmiana jego danych osobowych itp. itd. dzieje się gdzie indziej niż u nas. Nie mamy też możliwość łatwego podpięcia się pod odpowiednią bazę. Trzeba było więc stworzyć coś co nam umożliwi pracę z Federation Services bez posiadania Federation Services :) Celem tego też było napisanie tak kodu, by wykorzystać aktualną konfigurację jak się da (wszystkie procesy modyfikowania claims itp. mają się odpalić).

Ogólnie sprawa jest dość prosta, wystarczy tylko stworzyć odpowiedniego Principala z kodu w odpowiednim miejscu. Tak więc też zrobiłem:

// get_claims returns IEnumerable<Claim>
var identity = new ClaimsIdentity(get_claims());
var principal = new ClaimsPrincipal(identity);

// creates FedAuth cookie
var sessionToken = FederatedAuthentication
    .SessionAuthenticationModule
    .CreateSessionSecurityToken(principal
        , context: "debug_mode"
        , validFrom: ApplicationTime.Current.UtcDateTime
        , validTo: ApplicationTime.Current.AddMinutes(30).UtcDateTime
        , isPersistent: true);
FederatedAuthentication
    .SessionAuthenticationModule
    .AuthenticateSessionSecurityToken(sessionToken, true);

// if we are modifying incoming claims 
Thread.CurrentPrincipal = FederatedAuthentication
    .FederationConfiguration
    .IdentityConfiguration
    .ClaimsAuthenticationManager
    .Authenticate(string.Empty, principal);

HttpContext.Current.User = Thread.CurrentPrincipal;

Ale to nie działało… więc po 2h wkurzania się, i denerwowania odkryłem, że powyższy kod tworzy i przypisuje mi mój Principal jak trzeba, ale nie ustawia mu opcji IsAuthenticated na true.

Poprawienie tego było proste – wystarczyło dodać parametr do konstruktora ClaimsIdentity z nazwą authentication type (dowolny ciąg znaków) (linia numer 2):

// MODIFIED: debug_mode -> authentication type
var identity = new ClaimsIdentity(get_claims(), "debug_mode");

var principal = new ClaimsPrincipal(identity);

// creates FedAuth cookie
var sessionToken = FederatedAuthentication
    .SessionAuthenticationModule
    .CreateSessionSecurityToken(principal
        , context: "debug_mode"
        , validFrom: ApplicationTime.Current.UtcDateTime
        , validTo: ApplicationTime.Current.AddMinutes(30).UtcDateTime
        , isPersistent: true);
FederatedAuthentication
    .SessionAuthenticationModule
    .AuthenticateSessionSecurityToken(sessionToken, true);

// if we are modifying incoming claims 
Thread.CurrentPrincipal = FederatedAuthentication
    .FederationConfiguration
    .IdentityConfiguration
    .ClaimsAuthenticationManager
    .Authenticate(string.Empty, principal);

HttpContext.Current.User = Thread.CurrentPrincipal;

Domyślnie ClaimsIdentity ustawia IsAuthenticated na true wtedy kiedy AuthenticationType nie jest null :) I tak o to kolejne 2h z życia poszły sobie na spacer :)

2 KOMENTARZE

  1. **@Ja**

    nie sa :) ale zaznacze bardziej, roznica jest tutaj:

    `var identity = new ClaimsIdentity(get_claims());`
    na
    `var identity = new ClaimsIdentity(get_claims(), “debug_mode”);`

Comments are closed.