2016-09-28 18 views
9

Tôi đang thực hiện một IdentityServer4 Tôi đang làm cho 3 diferents proyects:Làm thế nào để sử dụng IdentityServer4 với và Javascript client với ClientCredentials ASP.NET Lõi

Tất cả dự án được tạo bằng ASP.NET Core, nhưng khách hàng JS sử dụng tệp tĩnh.

Tôi cần JS Client kết nối với API chỉ với mã thông báo nhận dạng (không phải mã thông báo truy cập) vì tôi chỉ cần có quyền truy cập vào API, tôi không cần quản lý xác thực người dùng.

Tôi đọc quickstarts gửi https://identityserver4.readthedocs.io/en/dev/quickstarts/1_client_credentials.html

Như tôi đã đọc Tôi cho rằng tôi cần phải sử dụng Type Đại Implicit và tôi không cần phải OpenID Connect, chỉ OAuth2.

Ngoài ra tôi đọc bài đăng này https://identityserver4.readthedocs.io/en/dev/quickstarts/7_javascript_client.html Nhưng họ sử dụng access token và tôi không cần điều đó, để kết nối với các API Tôi đang sử dụng oidc-client-js thư viện https://github.com/IdentityModel/oidc-client-js và tôi tìm cách để sử dụng với Type Đại Implicit nhưng các phương pháp mà tôi sử dụng chuyển hướng tôi đến trang http://localhost:5000/connect/authorize (Tôi nghĩ đây là khi tôi cần sử dụng OpenID Connect)

Cách tốt nhất để đạt được điều đó là gì? Tôi đã làm gì sai? Làm thế nào tôi có thể autenticate với api và gọi http://localhost:5001/values

IdentityServer Dự án

Config.cs

public static IEnumerable<Client> GetClients() 
     { 
      return new List<Client> 
      { 
       new Client 
       { 
        ClientId = "client", 
        ClientName = "JavaScript Client", 
        // no interactive user, use the clientid/secret for authentication 
        AllowedGrantTypes = GrantTypes.Implicit, 
        AllowAccessTokensViaBrowser = true, 



        RedirectUris = new List<string> 
        { 
         "http://localhost:5003/oidc-client-sample-callback.html" 
        }, 
        AllowedCorsOrigins = new List<string> 
        { 
         "http://localhost:5003" 
        }, 

        // scopes that client has access to 
        AllowedScopes = new List<string> 
        { 
         "api1" 
        } 
       } 
      }; 
     } 

Startup.cs

public void ConfigureServices(IServiceCollection services) 
    { 
     // configure identity server with in-memory stores, keys, clients and scopes 
     services.AddDeveloperIdentityServer() 
      .AddInMemoryScopes(Config.GetScopes()) 
      .AddInMemoryClients(Config.GetClients()); 
    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(LogLevel.Debug); 
     app.UseDeveloperExceptionPage(); 

     app.UseIdentityServer(); 
    } 

dự án API

Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 

    // Add framework services. 
    services.AddMvc(); 

    services.AddSingleton<ITodoRepository, TodoRepository>(); 

    services.AddCors(options => 
    { 
     // this defines a CORS policy called "default" 
     options.AddPolicy("default", policy => 
     { 
      policy.WithOrigins("http://localhost:5003") 
       .AllowAnyHeader() 
       .AllowAnyMethod(); 
     }); 
    }); 

    services.AddMvcCore() 
     .AddAuthorization() 
     .AddJsonFormatters(); 


} 

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    app.UseCors("default"); 

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
    { 
     Authority = "http://localhost:5000", 
     ScopeName = "api1", 

     RequireHttpsMetadata = false 
    }); 

    app.UseMvc(); 

} 

ValuesController.cs

[Route("api/[controller]")] 
    [Authorize] 
    public class ValuesController : Controller 
    { 
     // GET api/values 
     [HttpGet] 
     public IEnumerable<string> Get() 
     { 
      return new string[] { "value1", "value3" }; 
     } 

     // GET api/values/5 
     [HttpGet("{id}")] 
     public string Get(int id) 
     { 
      return "value"; 
     } 
} 

dự án khách hàng javascript

oidc-client-sample.html

<!DOCTYPE html> 
<html> 
<head> 
    <title>oidc-client test</title> 
    <link rel='stylesheet' href='app.css'> 
</head> 
<body> 
    <div> 
     <a href='/'>home</a> 
     <a href='oidc-client-sample.html'>clear url</a> 
     <label> 
      follow links 
      <input type="checkbox" id='links'> 
     </label> 
     <button id='signin'>signin</button> 
     <button id='processSignin'>process signin response</button> 
     <button id='signinDifferentCallback'>signin using different callback page</button> 
     <button id='signout'>signout</button> 
     <button id='processSignout'>process signout response</button> 
    </div> 

    <pre id='out'></pre> 

    <script src='oidc-client.js'></script> 
    <script src='log.js'></script> 
    <script src='oidc-client-sample.js'></script> 
</body> 
</html> 

oidc-khách hàng- mẫu vật .js

/////////////////////////////// 
// UI event handlers 
/////////////////////////////// 
document.getElementById('signin').addEventListener("click", signin, false); 
document.getElementById('processSignin').addEventListener("click", processSigninResponse, false); 
document.getElementById('signinDifferentCallback').addEventListener("click", signinDifferentCallback, false); 
document.getElementById('signout').addEventListener("click", signout, false); 
document.getElementById('processSignout').addEventListener("click", processSignoutResponse, false); 
document.getElementById('links').addEventListener('change', toggleLinks, false); 

/////////////////////////////// 
// OidcClient config 
/////////////////////////////// 
Oidc.Log.logger = console; 
Oidc.Log.level = Oidc.Log.INFO; 

var settings = { 
    authority: 'http://localhost:5000/', 
    client_id: 'client', 
    redirect_uri: 'http://localhost:5003/oidc-client-sample-callback.html', 
    response_type: 'token', 
    scope: 'api1' 
}; 
var client = new Oidc.OidcClient(settings); 

/////////////////////////////// 
// functions for UI elements 
/////////////////////////////// 
function signin() { 
    client.createSigninRequest({ data: { bar: 15 } }).then(function (req) { 
     log("signin request", req, "<a href='" + req.url + "'>go signin</a>"); 
     if (followLinks()) { 
      window.location = req.url; 
     } 
    }).catch(function (err) { 
     log(err); 
    }); 
} 
function api() { 
    client.getUser().then(function (user) { 
     var url = "http://localhost:5001/values"; 

     var xhr = new XMLHttpRequest(); 
     xhr.open("GET", url); 
     xhr.onload = function() { 
      log(xhr.status, JSON.parse(xhr.responseText)); 
     } 
     xhr.setRequestHeader("Authorization", "Bearer " + user.access_token); 
     xhr.send(); 
    }); 
} 

oidc-client-mẫu-callback.html

<!DOCTYPE html> 
<html> 
<head> 
    <title>oidc-client test</title> 
    <link rel='stylesheet' href='app.css'> 
</head> 
<body> 
    <div> 
     <a href="oidc-client-sample.html">back to sample</a> 
    </div> 
    <pre id='out'></pre> 
    <script src='log.js'></script> 
    <script src='oidc-client.js'></script> 
    <script> 
      Oidc.Log.logger = console; 
      Oidc.Log.logLevel = Oidc.Log.INFO; 
      new Oidc.OidcClient().processSigninResponse().then(function(response) { 
       log("signin response success", response); 
      }).catch(function(err) { 
       log(err); 
      }); 
    </script> 
</body> 
</html> 
+0

Tại sao không ẩn danh API và lưu một loạt công việc? Bạn sẽ phải mã hóa mật khẩu Client ID + Client Secret trong JavaScript, điều đó có nghĩa là chúng bị xâm phạm, không có cách nào để giữ bí mật trong JavaScript. – stevieg

+0

Có, tôi đang đọc nhiều hơn và tôi cần là Loại đại diện tiềm ẩn https://aaronparecki.com/2012/07/29/2/oauth2-simplified nhưng tôi không biết cách sử dụng chính xác –

+0

IdentityServer4 có api công khai loại này là những gì tôi đang cố gắng sử dụng. –

Trả lời

1

Theo như tôi thấy, mã của bạn nên làm việc, nó làm mọi thứ.

  1. Ứng dụng JavaScript (localhost: 5003) yêu cầu mã thông báo (function signin()). Điều này sẽ dẫn đến việc chuyển hướng đến IdentityServer
  2. Máy chủ IdentityServer (localhost: 5000) được thiết lập và cài đặt ứng dụng khách (Client.cs) khớp với yêu cầu. Mặc dù cấu hình bị thiếu đối với người dùng và tài nguyên: xem tại đây: https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Quickstarts/3_ImplicitFlowAuthentication/src/QuickstartIdentityServer/Startup.cs
  3. Ứng dụng JavaScript của bạn có "trang đích" chính xác, trang mà IdentityServer chuyển hướng trở lại sau khi đăng nhập thành công. Trang này nhặt token mới ban hành (new Oidc.OidcClient().processSigninResponse())
  4. JavaScript ứng dụng của bạn gửi token cùng API yêu cầu của nó (xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);)
  5. API của bạn (localhost: 5001) được thiết lập một cách chính xác và sẽ cho phép chống lại IdentityServer bạn

Vì vậy, tôi nghĩ mã là đúng, nhưng có một số hiểu lầm liên quan đến các điều khoản.

  • Bạn cần trợ cấp ngầm định. Hãy quên đi ClientCredentials, vì nó được thiết kế cho một quy trình làm việc khác và không nên được sử dụng trong trình duyệt, bởi vì bí mật của máy khách đang được tiếp xúc. Điều này có nghĩa là bất kỳ ai cũng có thể phát hành mã thông báo hợp lệ ("ăn cắp") và bảo mật của bạn bị xâm phạm. (Nếu bạn phải sử dụng ClientCredentials, hãy tạo phương thức proxy máy chủ).
  • Bạn cần cả OpenID Connect (OIDC) và OAuth2. (Đây không phải là định nghĩa chính xác !!) OIDC phát hành mã thông báo cho bạn ("ghi nhật ký người dùng vào"), trong khi OAuth2 xác thực mã thông báo. Đừng lo lắng, IdentityServer sẽ chăm sóc tất cả những điều đó.
  • Bạn cần mã thông báo truy cập. Mã thông báo nhận dạng được cấp cho người yêu cầu (máy chủ cục bộ của bạn: ứng dụng JavaScript 5003), mã thông báo truy cập phải được "gửi tiếp" tới API (localhost: 5001 API)
  • Chuyển hướng cho "đăng nhập" là bình thường. Đây là quy trình làm việc điển hình cho ứng dụng web: bạn rời khỏi ứng dụng của mình (localhost: 5003) và kết thúc bằng IdentityServer (http://localhost:5000). Sau khi đăng nhập thành công, bạn đang được chuyển hướng trở lại ứng dụng của bạn (localhost: 5003)
Các vấn đề liên quan