2015-01-26 4 views
6

Я пытаюсь следовать простому руководству mvcGettingStarted. Теперь я реализовал как GoogleAuthentication, так и FacebookAuthentication провайдеров, и все работает должным образом, я действительно могу войти в систему, и если я вхожу в систему с моим сервером идентификации, у меня также есть требования к ролям для каждого пользователя. Мне было интересно, что, если я хочу сохранить все претензии от внешних поставщиков? Простой пример. Это как мой Facebook настройки провайдера выглядит следующим образом:Thinktecture Identity Server v3 Как сохранить претензии от внешних поставщиков?

var facebookOptions = new FacebookAuthenticationOptions() { 
      AuthenticationType = "Facebook", 
      Caption = "Sign in with Facebook", 
      AppId = "*****", 
      AppSecret = "****", 
      SignInAsAuthenticationType = signInAsType, 
      Provider = new FacebookAuthenticationProvider() { 
       OnAuthenticated = (context) => { 

        foreach (var x in context.User) { 
         context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString())); 
        } 

        return Task.FromResult(context); 
       } 
      }, 
     }; 

     facebookOptions.Scope.Add("email"); 
     facebookOptions.Scope.Add("public_profile"); 
     facebookOptions.Scope.Add("user_friends"); 

     app.UseFacebookAuthentication(facebookOptions); 

В течение каждого цикла я пытаюсь сохранить все Facebook утверждает, что в идентичности, но когда я вернусь в SecurityTokenValidated обратного вызова, мой стиль hasn Это их.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() { 
      Authority = "https://localhost:44302/identity/", 
      ClientId = "my_client", 
      Scope = "openid profile roles email", 
      RedirectUri = "https://localhost:44302/", 
      ResponseType = "id_token token", 
      SignInAsAuthenticationType = "Cookies", 
      UseTokenLifetime = false, 
      Notifications = new OpenIdConnectAuthenticationNotifications() { 

       SecurityTokenValidated = async context => { 
        //let's clean up this identity 

        //context.AuthenticationTicket.Identity doesn't have the claims added in the facebook callback 
        var nid = new ClaimsIdentity(
         context.AuthenticationTicket.Identity.AuthenticationType, 
         Constants.ClaimTypes.GivenName, 
         Constants.ClaimTypes.Role); 
        ........ 

Это потому, что я манипулирую двумя разными Точками? Есть ли правильный способ достичь того, что я пытаюсь сделать? Спасибо.

ответ

4

Вы сделаете это в своей пользовательской реализации. По умолчанию используется заявка от внешнего поставщика. Документы в пользовательской службе пользователя: https://identityserver.github.io/Documentation/docsv2/advanced/userService.html

+0

ссылка приводит к 404 https://identityserver.github.io/Documentation/docs/advanced/userService.html – Rahatur

+0

ссылка исправлена ​​................... –

6

Как сказал @ brock-allen, пользовательская служба - это правильный путь, чтобы следовать. Так что я пошел дальше и реализовали простой UserService

public class UserService { 
    private static InMemoryUserService _service = null; 
    public static InMemoryUserService Get() { 
     if(_service == null) 
      _service = new InMemoryUserService(Users.Get()); 

     return _service; 
    } 
} 

зарегистрирован мой UserService в моей фабрике, как этот

public void Configuration(IAppBuilder app) { 
     AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; 
     JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

     var factory = InMemoryFactory.Create(
      users: Users.Get(), 
      clients: Clients.Get(), 
      scopes: Scopes.Get()); 
     factory.UserService = new Registration<IUserService>(resolver => UserService.Get()); 

..... 

(Конечно, это метод конфигурации внутри моего класса Startup)

Так что теперь Я могу аутентифицировать внешнего пользователя внутри обратного вызова аутентификации внешнего провайдера (в данном случае facebook), указав все необходимые мне претензии:

var facebookOptions = new FacebookAuthenticationOptions() { 
      AuthenticationType = "Facebook", 
      Caption = "Sign in with Facebook", 
      AppId = "******", 
      AppSecret = "*******", 
      SignInAsAuthenticationType = signInAsType, 
      Provider = new FacebookAuthenticationProvider() { 
       OnAuthenticated = (context) => { 

        foreach (var x in context.User) { 
         context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString())); 
        } 

        ExternalIdentity identity = new ExternalIdentity() { 
         Claims = context.Identity.Claims, 
         Provider = "Facebook", 
         ProviderId = "Facebook" 
        }; 
        SignInMessage signInMessage = new SignInMessage(); 

        UserService.Get().AuthenticateExternalAsync(identity, signInMessage); 


        return Task.FromResult(context); 
       } 
      }, 
     } 

Теперь я могу сделать

List<Claim> claims = await UserService.Get().GetProfileDataAsync(User as ClaimsPrincipal) as List<Claim>; 

И вижу, что мой пользователь имеет все претензии facebook предоставляемые во время аутентификации. Конечно, этот код предназначен только для тестирования, его можно улучшить.

+0

Я переживаю некоторую борьбу за понимание местных и внешних претензий. См. Http://stackoverflow.com/questions/28748000/confusion-over-local-authority-claims-and-external-provider-claims. Можете ли вы пролить свет на это? – Raj

+2

@ Daniele вы можете опубликовать весь код? Я очень заинтересован. Thx – mbrc

+1

Является ли AuthenticateExternalAsync метод расширения? Я не мог найти того, кто принимает эти аргументы. Тот, который я получил здесь, принимает только аргумент ExternalAuthenticationContext и не имеет перегрузки. –