2016-09-28 61 views
9

我实现了我提出3个diferents proyects IdentityServer4:如何使用IdentityServer4具有与ClientCredentials JavaScript客户端ASP.NET核心

所有项目都是使用ASP.NET Core创建的,但JS客户端使用静态文件。

我需要的JS客户端连接API只与身份令牌(不能访问令牌),因为我只需要访问的API,我不需要管理用户autentication。

我读了快速入门发布https://identityserver4.readthedocs.io/en/dev/quickstarts/1_client_credentials.html

当我读到我认为我需要用户的隐式类型大,我不需要ID连接,只有OAuth2用户。

而且我看到这篇文章 https://identityserver4.readthedocs.io/en/dev/quickstarts/7_javascript_client.html 但他们使用的访问令牌和我不需要的是,连接到API,我使用OIDC-客户JS库https://github.com/IdentityModel/oidc-client-js和我搜索与隐大类型使用方式但我使用的方法重定向到页面http://localhost:5000/connect/authorize(我认为这是当我需要使用OpenID连接)

什么是实现这一目标的最佳方法? 我有什么错? 我如何使用API​​ autenticate并调用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项目

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

JavaScript客户端项目

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匿名并保存一堆工作?您必须在JavaScript中对客户端ID +客户端秘密进行硬编码,这意味着他们已被入侵,无法保留JavaScript的秘密。 – stevieg

+0

是的,我阅读更多,我需要的是隐式盛大类型https://aaronparecki.com/2012/07/29/2/oauth2-simplified但我不知道如何正确使用它 –

+0

IdentityServer4有一个公共API键入这是我正在尝试使用。 –

回答

1

据我看到的,你的代码应该工作,它做的一切。

  1. 您的JavaScript-app(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重定向的页面。此页面拿起新发行的令牌(new Oidc.OidcClient().processSigninResponse()
  4. 你的JavaScript的应用程序将沿着它的API请求令牌(xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
  5. 你的API(本地主机:5001)设置正确,并授权对您的IdentityServer

所以我认为代码是正确的,但是对这些术语存在一些误解。

  • 您需要隐式授予。忘记ClientCredentials,因为它是为另一个工作流而设计的,不应该在浏览器中使用,因为客户端的秘密正在被暴露。这意味着任何人都可以发出有效的令牌(“窃取”),并且您的安全受到威胁。 (如果你必须使用ClientCredentials,创建一个服务器代理方法)。
  • 您需要OpenID Connect(OIDC)和OAuth2。 (这些不是准确的定义!!)OIDC为您颁发令牌(“将用户登录”),而OAuth2验证令牌。别担心,IdentityServer会照顾所有这些。
  • 您需要访问令牌。身份令牌是为请求者(您的localhost:5003 JavaScript应用程序)发出的,访问令牌应该“向前发送”到API(您的本地主机:5001 API)
  • “登录”的重定向是正常的。这是Web应用程序的典型工作流程:您离开您的应用程序(localhost:5003)并结束于IdentityServer(http://localhost:5000)。成功登录后,您将被重定向回您的应用程序(localhost:5003)
相关问题