2016-09-28 3 views
9

내가 3가 diferents의 proyects 만드는 중이 IdentityServer4 구현하고있다 :와 자바 스크립트 클라이언트 ClientCredentials와 IdentityServer4를 사용하는 방법 ASP.NET 코어

모든 프로젝트는 ASP.NET 코어로 생성되지만 JS 클라이언트는 정적 파일을 사용합니다.

JS 클라이언트는 API에 액세스해야하기 때문에 ID 토큰 (액세스 토큰 아님) 만 사용하여 API에 연결해야합니다. 사용자 인증을 관리 할 필요가 없습니다. 나는 내가 사용자에게 암시 그랜드 유형을 필요로하고 내가 오픈 ID에 연결 만 OAuth2를 필요 해달라고 고려 읽으면서 나는 퀵 스타트를 읽고있다

https://identityserver4.readthedocs.io/en/dev/quickstarts/1_client_credentials.html

을 게시 할 수 있습니다.

또한이 게시물 https://identityserver4.readthedocs.io/en/dev/quickstarts/7_javascript_client.html 을 읽을 그러나 그들은 토큰 액세스를 사용하고 난 도서관 https://github.com/IdentityModel/oidc-client-js-JS OIDC 클라이언트를 사용하고있는 API에 연결하고 나는 암시 그랜드 형식으로 사용하는 방법을 검색 할 것을 필요 없어요 하지만 내가 사용하는 방법은 http://localhost:5000/connect/authorize 페이지로 리디렉션됩니다 (이것이 OpenID Connect를 사용해야 할 때라고 생각합니다).

그게 가장 좋은 방법은 무엇입니까? 내가 뭘 잘못 했니? 어떻게 http://localhost:5001/values

IdentityServer 프로젝트

에게 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(); 
    } 

API 프로젝트

을 API로 autenticate 및 호출 할 수 있습니다

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"; 
     } 
} 

자바 스크립트 클라이언트 프로젝트

OIDC - 클라이언트 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 - 클라이언트 - 견본 의 .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 - 클라이언트 샘플 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

왜 API를 익명으로 만들고 여러 작업을 저장하지 않습니까? Client ID + Client Secret은 자바 스크립트로 하드 코딩해야합니다. 즉, 해킹 당했음을 의미하므로 자바 스크립트에 비밀을 유지할 방법이 없습니다. – stevieg

+0

예, 자세한 내용을 읽고 있는데 암시적인 그랜드 타입 https://aaronparecki.com/2012/07/29/2/oauth2-simplified가 필요하지만 올바르게 사용하는 방법을 모릅니다. –

+0

IdentityServer4에 공개 API가 있습니다. 이것은 내가 사용하려고하는 타입이다. –

답변

1

지금까지 내가 보는 바와 같이, 코드가 작동합니다, 그것은 모든 것을 않습니다.

  1. 자바 스크립트 앱 (localhost : 5003)이 토큰 (function signin())을 요청합니다. 그러면 IdentityServer로 리디렉션됩니다.
  2. IdentityServer (localhost : 5000)가 설정되고 클라이언트 설정 (Client.cs)이 요청과 일치합니다. 사용자 및 리소스에 대한 구성이 누락되었지만 여기를 참조하십시오. https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Quickstarts/3_ImplicitFlowAuthentication/src/QuickstartIdentityServer/Startup.cs
  3. JavaScript 응용 프로그램에는 로그인 성공 후 IdentityServer가 다시 리디렉션되는 올바른 "방문 페이지"가 ​​있습니다. 올바르게 설정하고 IdentityServer
  4. 에 대해 권한을 부여합니다 :이 페이지는 새로 발급 된 토큰을 집어 들고 ( new Oidc.OidcClient().processSigninResponse())
  5. 귀하의 자바 스크립트 응용 프로그램은 API 요청에 따라 토큰 (xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);)
  6. 귀하의 API가 (5001 로컬 호스트) 전송

코드가 맞다고 생각하지만 용어에 대한 오해가 있습니다.

  • 암시 적 승인이 필요합니다. ClientCredentials는 다른 워크 플로우 용으로 설계되었으므로 브라우저에서 사용하면 안되기 때문에 ClientCredentials는 잊어 버리십시오. 클라이언트 비밀이 노출되고 있기 때문입니다. 즉, 누구든지 유효한 토큰을 발급 ("훔치기")하여 보안이 손상 될 수 있습니다. ClientCredentials를 사용해야하는 경우 서버 프록시 메서드를 만듭니다.
  • OIDC (OpenID Connect)와 OAuth2가 모두 필요합니다. OAuth2가 토큰의 유효성을 검사하는 동안 OIDC는 사용자의 토큰 ("사용자를 기록합니다")을 발행합니다. IdentityServer가 모든 것을 처리하므로 걱정하지 마십시오.
  • 액세스 토큰이 필요합니다. 요청자 (localhost : 5003 JavaScript 응용 프로그램)에 대해 ID 토큰이 발행되고 액세스 토큰은 API (localhost : 5001 API)로 "전달"되어야합니다.
  • "로그인"의 리디렉션은 정상입니다. 웹 응용 프로그램의 일반적인 워크 플로입니다. 응용 프로그램 (localhost : 5003)을 종료하고 IdentityServer (http://localhost:5000)로 끝납니다. 로그인에 성공하면 응용 프로그램 (로컬 호스트 : 5003)으로 리디렉션됩니다.
관련 문제