2017-03-29 1 views
1

Ich habe einen Authentifizierungsdienst auf Basis von IdentityServer3 und einer einfachen MVC-Client-App und einer vom Authentifizierungsdienst gesicherten Shopper-API implementiert. Ich habe einen benutzerdefinierten UserService für IdentityServer implementiert, so dass der Authentifizierungsdienst mit unserem vorhandenen Benutzerdatenspeicher authentifiziert wird. Meine Shopper API erwartet eine Benutzer-ID in der Shopper Get-Anfrage. Derzeit enthält die Antwort vom Authentifizierungsdienst das Identitäts-Token und das Zugriffstoken, aber keine Benutzer-ID. Ich habe versucht, einen Benutzer-ID-Anspruch im AuthenticationResult von meiner benutzerdefinierten UserService.AuthenticateLocalAsync-Methode hinzuzufügen, aber ich sehe es nicht in meinem Client-App-Code. UserService.AuthenticateLocalAsync sieht wie folgt aus:Wie erhalte ich eine Benutzer-ID von IdentityServer in der Client-App, wenn ich ein Zugriffstoken einschließe?

try 
{ 
    var user = new shopper(_dbConnLib, context.UserName, context.Password); 
    var claims = new List<Claim> { new Claim("user_id", user.shopperid) }; 
    context.AuthenticateResult = new AuthenticateResult(user.shopperid, user.MemberDetail.billToAddress.FirstName, claims); 
} 
catch(shopperInitFromException ex) 
{ 
    context.AuthenticateResult = null; // Indicates username/password failure 
} 
return Task.FromResult(0); 

Und meine Client-Anwendung SecurityTokenValidated Handler wie folgt aussieht:

SecurityTokenValidated = async n => 
{ 
    var nid = new ClaimsIdentity(
     n.AuthenticationTicket.Identity.AuthenticationType, 
     Constants.ClaimTypes.GivenName, 
     Constants.ClaimTypes.Role); 

    var userInfoClient = new UserInfoClient(
     new Uri(n.Options.Authority + "/connect/userinfo").ToString()); 

    var userInfo = await userInfoClient.GetAsync(n.ProtocolMessage.AccessToken); 
    userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Type, ui.Value))); 

    nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); 

    nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); 

    //nid.AddClaim(new Claim("user_id", n.ProtocolMessage.UserId)); 

    nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); 

    n.AuthenticationTicket = new AuthenticationTicket(
     nid, 
     n.AuthenticationTicket.Properties); 
} 

Wenn ich durch, dass im Debugger Schritt userInfo.Claims hat immer eine Zählung von 0 Wie kann ich einen Anspruch mit der eindeutigen Kennung des Benutzers zurückbekommen? Oder kann ich es vom Identitäts- oder Zugriffstoken bekommen? Oder sollte ich die Token einfach an die Shopper-API übergeben und die ID aus den Token bestimmen lassen?

Antwort

0

Ich denke, dass ich die Antwort haben kann. Soweit ich das beurteilen kann, scheinen die Ansprüche, die ich in den AuthenticateResult-Konstruktor in meiner Überschreibung von AuthenticateLocalAsync einbeziehe, nirgendwohin zu gehen. Aber die Ansprüche, die ich in meine Überschreibung von GetProfileDataAsync einbeziehe, erscheinen im Token. Mein GetProfileDataAsync-Code, der die Ansprüche richtig zu setzen scheint, sieht wie folgt aus:

public override Task GetProfileDataAsync(ProfileDataRequestContext context) 
{ 
    var user = new shopper(_dbConnLib, context.Subject.FindFirst("sub").Value); 
    var claims = new List<Claim> { new Claim("sub", user.shopperid), new Claim("acr_level", "level 0"), new Claim("amr", "anonymous") }; 
    context.IssuedClaims = claims; 
    return Task.FromResult(0); 
} 

Mein AuthenticateLocalAsync Code, die Ansprüche in der AuthenticateResult setzt, die ich nie sieht aus wie dies in meinem Client-Anwendung Code sehen:

public override Task AuthenticateLocalAsync(LocalAuthenticationContext context) 
{ 
    // TODO: Handle AddshopperToBasketException in UserService.AuthenticateLocalAsync 
    try 
    { 
     var user = new shopper(_dbConnLib, context.UserName, context.Password); 
     var claims = new List<Claim> { new Claim("acr_level", "level 0"), new Claim("amr", "anonymous") }; 
     context.AuthenticateResult = new AuthenticateResult(user.shopperid, user.MemberDetail.billToAddress.FirstName, claims); 
    } 
    catch(shopperInitFromException ex) 
    { 
     context.AuthenticateResult = null; // Indicates username/password failure 
    } 
    return Task.FromResult(0); 
} 
Verwandte Themen