joaojosefilho/vuejsOidcClient

Silent Renew Frame window timed out

Closed this issue · 18 comments

image
When trying to loginSilent I get this error.

Oi @patrickmonteiro,
Já conseguiu resolver o problema?
Eu não entendi o momento em que acontece o erro. Qual método lança essa exceção?

Olá @joaojosefilho , sempre que tento fazer o método signinSilent() ele me devolve este erro. Utilizei como base exatamente a forma que vcs fazem, mas não funcionou.

Eu procurei no meu código e não encontrei o método signinSilent(). Esse erro é lançado após a tentativa de login?

Este método é o oidc-client.js, ele faz a autenticação silenciosa quando o token é expirado.
image

Beleza, então o problema é quando você tenta atualizar o token de acesso. Eu também tive um problema para atualizar o token de acesso. Meu problema estava no Back-End. Eu estava utilizando o IdentityServer4. Eu tinha configurado uma variável de forma errada. Você está utilizando qual framework de segurança no Back-End?

Estamos usando Identityserver 4. Porém ao tentar renovar, aparece este erro como se não conseguisse abrir o frame invisivel. Qual foi a sua solução ?

Esse link mostra a solução
IdentityModel/oidc-client-js#567

Eu fiz um repositório com uma implementação do IndentityServer4
https://github.com/joaojosefilho/IdentityServer4AndApi

Eu usei essa implementação para criar o exemplo do oidc-client usando o vue-JS
https://github.com/joaojosefilho/vuejsOidcClient

Eu integrei o IdentityServer4AndApi e o vuejsOidcClient. O token está sendo atualizado corretamente nessa integração. Na minha implementação eu utilizo o silentRenewCallback() para atualizar o token.

Bom dia @patrickmonteiro, conseguiu solucionar seu problema?

Eu havia respondido, mas acho que estava com algum problema na internet.
Eu ainda estou avaliando com o pessoal do back-end, fizemos as configurações baseadas no seu projeto, mas ainda sim recebo o erro de Frame Windows time out.
Você sabe me dizer se posso chamar o signinSilent a qualquer momento?

Não sei dizer.

Para ficar testando a atualização do token de forma rápida, eu modificava a variável AccessTokenLifetime no BackEnd. Essa variável define o tempo de vida do token de acesso. No exemplo abaixo, depois de 90 segundos o token de acesso é invalidado.
Ex:
//Access token life time is 90 seconds (1 min e 30 se)
$ AccessTokenLifetime = 90

No Front-End, a variável accessTokenExpiringNotificationTime é responsável por definir o tempo de antecedência que o oidc-client tentará renovar o token de acesso.
Ex:
//Já que são 10 segundos, o oidc-client vai tentar renovar o acess token no segundo 80 (90 - 10 = 80).
$ accessTokenExpiringNotificationTime: 10

Quando chegar no segundo 80, o gatilho addAccessTokenExpiring vai ser ativado. Esse gatilho é responsável por chamar o método de atualização do token.
Ex:
mgr.events.addAccessTokenExpiring(function () {
console.log('AccessToken Expiring:', arguments);
});

Existem dois métodos para atualizar. signinSilent() e signinSilentCallback. Eu usei o signinSilentCallback.

https://github.com/joaojosefilho/vuejsOidcClient/blob/master/static/silent-renew.html

@joaojosefilho isso me esclarece mais algumas coisas que eu não conhecia.
Farei o teste agora pela manhã novamente, e verificarei se funcionará.
Agradeço sua atenção.

image

Começo a desconfiar do webpack do Quasar.

Existe um problema na biblioteca, que outras pessoas não conseguem resolver também: IdentityModel/oidc-client-js#172

Pelo que eu entendi o @freemanfx concertou o problema corrigindo o redirecionamento da página. No Back-End é necessária fazer a configuração de conexão entre o IndentityServer4 e o cliente JavaScripty(No seu caso, o cliente é o Quasar).
https://github.com/joaojosefilho/IdentityServer4AndApi/blob/master/IdentityServer4.IDP/Config.cs

No link acima, eu instancio um cliente. Nele, eu declaro alguns atributos necessários para a conexão

 new Client
                {
                    ClientName = "vuejs", //Nome do Cliente Java Scripty
                    ClientId = "vuejsclient" //Id do Cliente Java Scripty, 
                    AllowedGrantTypes=GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser=true,
                    AccessTokenType = AccessTokenType.Reference, 
                    UpdateAccessTokenClaimsOnRefresh = true, 
                    AllowOfflineAccess = true,                    
                    RequireConsent = false, 
                    //AccessTokenLifetime = 50,                    
                    RedirectUris = new List<string>()
                    {
                        "http://localhost:8080/static/callback.html",
                        "http://localhost:8080/static/silent-renew.html"
                    },                    
                    PostLogoutRedirectUris = {
                        "http://localhost:8080/index.html"
                    },
                    AllowedCorsOrigins = {
                        "http://localhost:8080"
                    },                    
                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Address,
                        "roles",
                        "identityserver4api",
                        "country",
                        "subscriptionlevel"
                    },
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    
                }     

É necessário que que a variável RedirectUris tenha o link da página html responsável pelo atualização do token de acesso (No meu caso: "http://localhost:8080/static/silent-renew.html").

No Front-End você tem que declarar os atributos do oidc-client de acordo com o cliente IdentityServer4 instanciado

var mgr = new Oidc.UserManager({
  userStore: new Oidc.WebStorageStateStore({ store: window.localStorage }),
  authority: 'https://localhost:44321',
  client_id: 'vuejsclient', //Id do Clinte Instanciado no IdentityServer4
  redirect_uri: 'http://localhost:8080/static/callback.html',
  response_type: 'id_token token',
  scope: 'openid profile address roles identityserver4api country subscriptionlevel offline_access',
  post_logout_redirect_uri: 'http://localhost:8080/index.html',
  silent_redirect_uri: 'http://localhost:8080/static/silent-renew.html',
  accessTokenExpiringNotificationTime: 10,
  automaticSilentRenew: true,
  filterProtocolClaims: true,
  loadUserInfo: true
})

Note que o atributo silent_redirect_uri (e vários outros atributos) está instanciado da mesma forma que o do cliente IdentityServer4. O atributo silent_redirect_uri é responsável por armazenar o caminho para a página html que atualiza o token (https://github.com/joaojosefilho/vuejsOidcClient/blob/master/static/silent-renew.html).

O link abaixo mostra os conceitos iniciais de conexão entre o IndentityServer4 e um cliente JavaScripty
http://docs.identityserver.io/en/release/quickstarts/7_javascript_client.html

Bom dia @patrickmonteiro, alguma novidade?

@joaojosefilho só tive tempo de responder agora, ainda falha em nosso projeto.
Preciso tirar um tempo para efetuar mais alguns testes.

@joaojosefilho feche esta issue pois ainda não pude dar continuidade nos testes com o silent renew.
Caso eu tenha alguma novidade, nós reabrimos.

Beleza