2016-08-12 118 views
1

我已经开始使用ASOS与OpenID Connect服务器一起玩,通过实施资源所有者密码凭证授予。但是,当我使用邮递员测试它时,我得到了通用500内部服务器错误。OpenID Connect服务器与ASOS,.NET核心管道

这是我的代码,为您的调试乐趣。感谢您的反馈。

感谢

-Biruk

这里是我的Startup.cs

public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 

     services.AddAuthentication(options => { 
      options.SignInScheme = "ServerCookie"; 
     }); 


     services.AddApplicationInsightsTelemetry(Configuration); 

     services.AddMvc(); 

     services.AddSession(options => { 
      options.IdleTimeout = TimeSpan.FromMinutes(30); 
     }); 
    } 




    public void Configure(IApplicationBuilder app, IHostingEnvironment env, LoggerFactory loggerFactory) 
    { 

     app.UseOAuthValidation(); 


     app.UseOpenIdConnectServer(options => { 
      // Create your own authorization provider by subclassing 
      // the OpenIdConnectServerProvider base class. 
      options.Provider = new AuthorizationProvider(); 

      // Enable the authorization and token endpoints. 
      // options.AuthorizationEndpointPath = "/connect/authorize"; 
      options.TokenEndpointPath = "/connect/token"; 

      // During development, you can set AllowInsecureHttp 
      // to true to disable the HTTPS requirement. 
      options.ApplicationCanDisplayErrors = true; 
      options.AllowInsecureHttp = true; 

      // Note: uncomment this line to issue JWT tokens. 
      // options.AccessTokenHandler = new JwtSecurityTokenHandler(); 
     }); 

     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     app.UseApplicationInsightsRequestTelemetry(); 

     app.UseApplicationInsightsExceptionTelemetry(); 

     app.UseMvc(); 
    } 

,这里是我的

public sealed class AuthorizationProvider : OpenIdConnectServerProvider 
{ 
    public Task<User> GetUser() 
    { 

     return Task.Run(()=> new User { UserName = "biruk60", Password = "adminUser123" }); 
    } 
    // Implement OnValidateAuthorizationRequest to support interactive flows (code/implicit/hybrid). 
    public override Task ValidateTokenRequest(ValidateTokenRequestContext context) 
    { 
     // Reject the token request that don't use grant_type=password or grant_type=refresh_token. 
     if (!context.Request.IsPasswordGrantType() && !context.Request.IsRefreshTokenGrantType()) 
     { 
      context.Reject(
       error: OpenIdConnectConstants.Errors.UnsupportedGrantType, 
       description: "Only resource owner password credentials and refresh token " + 
          "are accepted by this authorization server"); 

      return Task.FromResult(0); 
     } 

     // Since there's only one application and since it's a public client 
     // (i.e a client that cannot keep its credentials private), call Skip() 
     // to inform the server the request should be accepted without 
     // enforcing client authentication. 
     context.Skip(); 

     return Task.FromResult(0); 
    } 



    public override async Task HandleTokenRequest(HandleTokenRequestContext context) 
    { 
     //// Resolve ASP.NET Core Identity's user manager from the DI container. 
     //var manager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>(); 

     // Only handle grant_type=password requests and let ASOS 
     // process grant_type=refresh_token requests automatically. 
     if (context.Request.IsPasswordGrantType()) 
     { 
      // var user = await manager.FindByNameAsync(context.Request.Username); 

      var user = await GetUser();//new { userName = "[email protected]", password = "adminUser123" }; 
      if (user == null) 
      { 
       context.Reject(
        error: OpenIdConnectConstants.Errors.InvalidGrant, 
        description: "Invalid credentials."); 

       return; 
      } 

      if (user != null && (user.Password == context.Request.Password)) 
      { 




       var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); 

       // Note: the name identifier is always included in both identity and 
       // access tokens, even if an explicit destination is not specified. 
       // identity.AddClaim(ClaimTypes.NameIdentifier, await manager.GetUserId(user)); 

       // When adding custom claims, you MUST specify one or more destinations. 
       // Read "part 7" for more information about custom claims and scopes. 
       identity.AddClaim("username", "biruk60", 
        OpenIdConnectConstants.Destinations.AccessToken, 
        OpenIdConnectConstants.Destinations.IdentityToken); 

       // Create a new authentication ticket holding the user identity. 
       var ticket = new AuthenticationTicket(
        new ClaimsPrincipal(identity), 
        new AuthenticationProperties(), 
        context.Options.AuthenticationScheme); 

       // Set the list of scopes granted to the client application. 
       ticket.SetScopes(
        /* openid: */ OpenIdConnectConstants.Scopes.OpenId, 
        /* email: */ OpenIdConnectConstants.Scopes.Email, 
        /* profile: */ OpenIdConnectConstants.Scopes.Profile); 

       // Set the resource servers the access token should be issued for. 
       // ticket.SetResources("resource_server"); 

       context.Validate(ticket); 
      } 
     } 
    } 


} 

我在做什么错。我可以把它放在调试模式下,并通过它没有任何错误,它只是500内部服务器错误在小提琴手和邮递员。

回答

1

这里是你可能看到异常:

System.InvalidOperationException:一个唯一的标识符无法找到产生一个“子”要求:一定要加上“ClaimTypes.NameIdentifier”要求。

添加一个ClaimTypes.NameIdentifier索赔,它应该工作。

+1

这样做。谢谢凯文! – BHR

+0

@基兰你的问题与这个问题完全无关,恐怕。您应该联系微软并询问他们是否可以为您构建一个小样本。 – Pinpoint