2017-02-13 125 views
2

我的令牌缺少刷新和角色屬性。我正在使用OpenIddict。該代碼直到今天仍然有效,它仍然可以在家用電腦上運行,但不能工作。刷新令牌和角色丟失(OpenIddict)

我很確定我做錯了什麼,但由於我比較了startup.cs,AuthorizationController.cs和他們是一樣的(工作和家庭),我需要一些幫助,可能是什麼問題的根源。

我需要爲用戶登錄角色,因爲我的Angular2應用程序需要知道用戶可以在網頁上做什麼。

要求我派:

Request

工作響應:

Work response

首頁響應:

Home response

的啓動代碼(

services.AddOpenIddict<int>() 
        .AddEntityFrameworkCoreStores<AppDbContext>() 
        .AddMvcBinders() 
        .EnableTokenEndpoint("/API/authorization/token") 
        .AllowPasswordFlow() 
        .AllowRefreshTokenFlow() 
        .UseJsonWebTokens() 
        .AddEphemeralSigningKey()  //todo naj bi bil pravi certifikat, če odstranič to vrstico ne dela in vidiš error. 
        .SetAccessTokenLifetime(TimeSpan.FromMinutes(30)) 
        .SetRefreshTokenLifetime(TimeSpan.FromDays(14)) 
        .DisableHttpsRequirement(); 

控制器代碼(又:同一家庭計算機上):再次家用計算機)上相同

public class AuthorizationController : BaseController 
{ 
    public AuthorizationController(AppDbContext context, OpenIddictApplicationManager<OpenIddictApplication<int>> applicationManager, SignInManager<AppUser> signInManager, UserManager<AppUser> userManager) : base(context, applicationManager, signInManager, userManager) 
    { 
    } 

    [Authorize, HttpGet("authorize")] 
    public async Task<IActionResult> Authorize(OpenIdConnectRequest request) 
    { 
     Debug.Assert(request.IsAuthorizationRequest(), 
      "The OpenIddict binder for ASP.NET Core MVC is not registered. " + 
      "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); 

     // Retrieve the application details from the database. 
     var application = await applicationManager.FindByClientIdAsync(request.ClientId, HttpContext.RequestAborted); 
     if (application == null) 
     { 
      return View("Error", new ErrorViewModel 
      { 
       Error = OpenIdConnectConstants.Errors.InvalidClient, 
       ErrorDescription = "Details concerning the calling client application cannot be found in the database" 
      }); 
     } 

     // Flow the request_id to allow OpenIddict to restore 
     // the original authorization request from the cache. 
     return View(new AuthorizeViewModel 
     { 
      ApplicationName = application.DisplayName, 
      RequestId = request.RequestId, 
      Scope = request.Scope 
     }); 
    } 

    [HttpPost("token"), Produces("application/json")] 
    public async Task<IActionResult> Exchange(OpenIdConnectRequest request) 
    { 
     Debug.Assert(request.IsTokenRequest(), 
      "The OpenIddict binder for ASP.NET Core MVC is not registered. " + 
      "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); 

     if (request.IsPasswordGrantType()) 
     { 
      var user = await userManager.FindByNameAsync(request.Username); 
      if (user == null) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The email/password couple is invalid." 
       }); 
      } 

      // Ensure the user is allowed to sign in. 
      if (!await signInManager.CanSignInAsync(user)) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The specified user is not allowed to sign in." 
       }); 
      } 

      // Reject the token request if two-factor authentication has been enabled by the user. 
      if (userManager.SupportsUserTwoFactor && await userManager.GetTwoFactorEnabledAsync(user)) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The specified user is not allowed to sign in." 
       }); 
      } 

      // Ensure the user is not already locked out. 
      if (userManager.SupportsUserLockout && await userManager.IsLockedOutAsync(user)) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The username/password couple is invalid." 
       }); 
      } 

      // Ensure the password is valid. 
      if (!await userManager.CheckPasswordAsync(user, request.Password)) 
      { 
       if (userManager.SupportsUserLockout) 
       { 
        await userManager.AccessFailedAsync(user); 
       } 

       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The username/password couple is invalid." 
       }); 
      } 

      if (userManager.SupportsUserLockout) 
      { 
       await userManager.ResetAccessFailedCountAsync(user); 
      } 

      // Create a new authentication ticket. 
      var ticket = await CreateTicketAsync(request, user); 

      return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); 
     } 

     else if (request.IsRefreshTokenGrantType()) 
     { 
      // Retrieve the claims principal stored in the refresh token. 
      var info = await HttpContext.Authentication.GetAuthenticateInfoAsync(
       OpenIdConnectServerDefaults.AuthenticationScheme); 

      // Retrieve the user profile corresponding to the refresh token. 
      var user = await userManager.GetUserAsync(info.Principal); 
      if (user == null) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The refresh token is no longer valid." 
       }); 
      } 

      // Ensure the user is still allowed to sign in. 
      if (!await signInManager.CanSignInAsync(user)) 
      { 
       return BadRequest(new OpenIdConnectResponse 
       { 
        Error = OpenIdConnectConstants.Errors.InvalidGrant, 
        ErrorDescription = "The user is no longer allowed to sign in." 
       }); 
      } 

      // Create a new authentication ticket, but reuse the properties stored 
      // in the refresh token, including the scopes originally granted. 
      var ticket = await CreateTicketAsync(request, user, info.Properties); 

      return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); 
     } 

     return BadRequest(new OpenIdConnectResponse 
     { 
      Error = OpenIdConnectConstants.Errors.UnsupportedGrantType, 
      ErrorDescription = "The specified grant type is not supported." 
     }); 
    } 

    private async Task<AuthenticationTicket> CreateTicketAsync(
     OpenIdConnectRequest request, AppUser user, 
     AuthenticationProperties properties = null) 
    { 
     // Create a new ClaimsPrincipal containing the claims that 
     // will be used to create an id_token, a token or a code. 
     var principal = await signInManager.CreateUserPrincipalAsync(user); 

     // Note: by default, claims are NOT automatically included in the access and identity tokens. 
     // To allow OpenIddict to serialize them, you must attach them a destination, that specifies 
     // whether they should be included in access tokens, in identity tokens or in both. 

     foreach (var claim in principal.Claims) 
     { 
      // In this sample, every claim is serialized in both the access and the identity tokens. 
      // In a real world application, you'd probably want to exclude confidential claims 
      // or apply a claims policy based on the scopes requested by the client application. 
      claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken, 
            OpenIdConnectConstants.Destinations.IdentityToken); 
     } 

     // Create a new authentication ticket holding the user identity. 
     var ticket = new AuthenticationTicket(principal, properties, 
      OpenIdConnectServerDefaults.AuthenticationScheme); 

     if (!request.IsRefreshTokenGrantType()) 
     { 
      // Set the list of scopes granted to the client application. 
      // Note: the offline_access scope must be granted 
      // to allow OpenIddict to return a refresh token. 
      ticket.SetScopes(new[] { 
       OpenIdConnectConstants.Scopes.OpenId, 
       OpenIdConnectConstants.Scopes.Email, 
       OpenIdConnectConstants.Scopes.Profile, 
       OpenIdConnectConstants.Scopes.OfflineAccess, 
       OpenIddictConstants.Scopes.Roles 
      }.Intersect(request.GetScopes())); 
     } 
     ticket.SetResources("OpPISWeb");  //also in startup.cs 

     return ticket; 
    } 
} 

對於解碼id_token我使用angular-jwt

return this.http.post('api/authorization/token', this.encodeObjectToParams(data), options) 
    .map(res => res.json()) 
    .map((tokens: AuthTokenModel) => 
    { 
     console.log("loged in", tokens); 
     let now = new Date(); 
     tokens.expiration_date = new Date(now.getTime() + tokens.expires_in * 1000).getTime().toString(); 

     localStorage.setItem('id_token', tokens.access_token); 
     localStorage.setItem('refresh_token', tokens.refresh_token); 

     const profile = this.jwtHelper.decodeToken(tokens.id_token) as ProfileModel; 
     const roles: string[] = typeof profile.role === "string" ? [profile.role] : profile.role; 
     const userProfile: Profile = new Profile(parseInt(profile.sub), roles); 
     localStorage.setItem('profile', JSON.stringify(userProfile)); 

     this.refreshTokens(tokens.expires_in * 1000 * 0.8); 

     return profile; 
    }); 
+1

這是一個錯誤,由ASOS(OpenIddict背後的OIDC庫)中最近的格式更改引起的。我現在就在上面,所以期待在接下來的15分鐘裏有一個錯誤修復和一個新的軟件包。 – Pinpoint

回答