2015-07-13 14 views
13

Tôi đang cố gắng thiết lập Máy chủ danh tính của Thinktecture 3, nhưng dường như tôi không nhận được mã thông báo làm mới khi trao đổi mã ủy quyền (hoặc khi sử dụng luồng ResourceOwner, nhưng tôi sẽ tập trung vào mã ủy quyền vì nó quan trọng hơn với tôi ngay bây giờ). Tôi lấy lại mã thông báo truy cập và có thể sử dụng chúng để xác thực tốt, nhưng nó dường như thậm chí không tạo ra mã thông báo làm mới mà tôi đang mong đợi để lấy lại. Có điều gì đặc biệt mà tôi cần làm để có được Identity Server trả về mã thông báo làm mới không?Máy chủ Identity không trả về mã thông báo làm mới

Tôi đã xem qua tài liệu nhưng chưa thấy bất kỳ điều gì mà tôi đã thiết lập sai và điều duy nhất trên trang của họ trên refresh tokens mà tôi không làm là yêu cầu rõ ràng phạm vi "offline_access" khi gửi người dùng đến đó để xác thực, bởi vì bất cứ khi nào tôi thử tôi nhận được lỗi "phạm vi không hợp lệ". Vì vậy, tôi đang sử dụng cách phân tích của Thinktecture "Yêu cầu phạm vi offline_access (thông qua mã hoặc luồng chủ sở hữu tài nguyên)" có nghĩa là phạm vi offline_access là một thứ được tự động yêu cầu dựa trên luồng bạn đang sử dụng.

Tôi đã cố gắng để làm theo các ứng dụng mẫu của họ (Và các mã nguồn cho Owin Middleware hiện từ Katana Project) như tốt nhất mà tôi có thể, và thiết lập của tôi là như sau:

  • Tôi đã tạo khách hàng sử dụng lớp khách hàng của họ, chỉ định theo cách thủ công như sau:
     
    var client = new Client() 
    { 
        ClientId = "SomeId", 
        ClientName = "Client with Authentication Code Flow", 
        RequireConsent = false, //Setting this to true didn't help 
        Flow = Flows.AuthorizationCode, 
        ClientSecrets = new List() { 
         new ClientSecret("secret") 
        }, 
        RedirectUris = new List() 
        { 
         "localhost:/specific-redirect-path" 
        } 
    };
  • Tôi đang thực hiện cuộc gọi tới điểm cuối ủy quyền như sau:
     
    var authorizationEndpoint = 
        AuthorizationEndpointBase + 
        "?client_id=" + Uri.EscapeDataString(Options.ClientId) + 
        "&scope=Default" + 
        "&response_type=code" + 
        "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + 
        "&state=" + Uri.EscapeDataString(state); 
    Response.Redirect(authorizationEndpoint);
    trong đó "Mặc định" là phạm vi tôi đã tạo.
  • Trong callback của tôi, tôi gọi là thiết bị đầu cuối mã thông báo như sau:
     
    IReadableStringCollection query = Request.Query; 
    string code = getValueFromQueryString("code", query); 
    var tokenRequestParameters = new List>() 
        { 
         new KeyValuePair("client_id", Options.ClientId), 
         new KeyValuePair("redirect_uri", GenerateRedirectUri()), 
         new KeyValuePair("client_secret", Options.ClientSecret), 
         new KeyValuePair("code", code), 
         new KeyValuePair("grant_type", "authorization_code"), 
        }; 
    var requestContent = new FormUrlEncodedContent(tokenRequestParameters); 
    HttpResponseMessage response = await _httpClient.PostAsync(TokenEndpoint, requestContent, Request.CallCancelled); 
    response.EnsureSuccessStatusCode(); 
    string oauthTokenResponse = await response.Content.ReadAsStringAsync(); 
    

Khi tôi thực hiện cuộc gọi đến các thiết bị đầu cuối thẻ, đăng nhập của tôi trên nhận dạng máy chủ sẽ hiển thị như sau (sau khi xác nhận của mã uỷ quyền):

 iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.TokenRequestValidator]: 7/13/2015 1:44:07 PM +00:00 -- Token request validation success 
    { 
     "ClientId": "SomeId", 
     "ClientName": "Client with Authentication Code Flow", 
     "GrantType": "authorization_code", 
     "AuthorizationCode": "f8f795e649044067ebd96a341c5af8c3" 
    } 
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Creating token response 
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Processing authorization code request 
    Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating access token 
    Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating reference access token 
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 7/13/2015 1:44:07 PM +00:00 -- End token request 
    iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.TokenResult]: 7/13/2015 1:44:07 PM +00:00 -- Returning token response.

Tôi không chắc chắn điều gì khác sẽ phù hợp, vì vậy tôi sẽ cung cấp thêm thông tin khi cần.

+0

Xin chào, xin lỗi vì nhận xét không liên quan, nhưng tôi có thể lấy mẫu bạn đã tạo bằng máy chủ nhận dạng tạo mã thông báo làm mới, v.v ... không? –

+0

Đáng tiếc, tôi đã xây dựng nó như là một phần của một nhân viên tăng cường mà tôi không còn trên, vì vậy tôi không có quyền truy cập vào các codebase cũng không được phép đăng nó. –

Trả lời

27

Bạn phải yêu cầu rõ ràng 'offline_access' trong yêu cầu của mình. Tách các phạm vi khác mà bạn yêu cầu với một khoảng trắng. (Trong ví dụ của tôi dưới đây tôi đang thay thế 'Default' với 'MyApi' để được rõ ràng rằng chúng ta đang nói về một phạm vi xác định bởi ứng dụng của bạn.)

&scope=MyApi offline_access 

Tuy nhiên, bạn cũng phải cấp mà khách hàng bên phải để xem mã thông báo làm mới, nó không chỉ xảy ra dựa trên luồng bạn chọn:

var client = new Client() 
{ 
    ... //All the stuff you were doing before 

    ScopeRestrictions = new List<string> 
    { 
     "MyApi", 
     StandardScopes.OfflineAccess.Name, //"offline_access" -for refresh tokens 
     //Other commonly requested scopes: 
     //StandardScopes.OpenId.Name, //"openid" 
     //StandardScopes.Email.Name, //"email" 

    }, 
} 

Bạn có thể cần phải thêm 'offline_access' vào cửa hàng phạm vi của mình. Cửa hàng phạm vi là danh sách các phạm vi mà Identity Server biết. Câu hỏi của bạn không đề cập đến cách cửa hàng phạm vi của bạn được thiết lập trong dự án của bạn, vì vậy bạn có thể đã có nó. Nhưng nếu điều trên không ngay lập tức làm việc cho bạn, bạn có thể muốn xem xét mã như thế này trong ví dụ bạn đang làm việc và thêm OfflineAccess.

var scopeStore = new InMemoryScopeStore(new Scope[]{ 
    StandardScopes.OpenId, 
    StandardScopes.Profile, 
    StandardScopes.Email, 
    StandardScopes.OfflineAccess, //<--- ensure this is here to allow refresh tokens 
    new Scope{ 
     Enabled = true, 
     Name = "MyApi" 
    }, 
} 
+1

Cảm ơn, điều đó đã làm được!Tôi không biết làm thế nào tôi rút nó ra, nhưng bằng cách nào đó phạm vi đã không được bao gồm khi tôi thêm các StandardScopes vào cơ sở dữ liệu, và tôi vẫn cố gắng bỏ lỡ nó khi tự nhìn chúng sớm hơn, đó là lý do tại sao tôi nghĩ rằng có lẽ nó được xác định một cách kỳ diệu. Điều này làm cho MUCH có ý nghĩa hơn. –

+2

Tôi đã quên bao gồm 'StandardScopes.OfflineAccess' trong cửa hàng phạm vi của tôi, cảm ơn vì đã đề cập đến phần đó. – Joshua

+1

Lưu ý: StandardScopes.All không bao gồm phạm vi truy cập ngoại tuyến. (Đó là rất lạ trong quan điểm của tôi). – jinavar1

Các vấn đề liên quan