public JObject Token(FormDataCollection request) { var client = AuthenticateClient(Request, request); AccessKey accessKey = null; var grantType = GetRequiredParameter(request, "grant_type"); switch (grantType) { case "authorization_code": { var code = GetRequiredParameter(request, "code"); var redirectUri = GetRequiredParameter(request, "redirect_uri"); Guid authCode; if (!Guid.TryParse(code, out authCode)) { ThrowHttpResponse(HttpStatusCode.Forbidden, "Invalid authorization code!"); } // find a valid grant by authorization code var grant = DataContext.OAuthGrant.Get(authCode); if (grant == null || grant.ClientID != client.ID || grant.Type != (int)OAuthGrantType.Code || grant.RedirectUri != redirectUri) { ThrowHttpResponse(HttpStatusCode.Forbidden, "Invalid authorization code!"); } if (DateTime.UtcNow > grant.Timestamp.AddMinutes(10)) { ThrowHttpResponse(HttpStatusCode.Forbidden, "Invalid authorization code!"); } grant.AuthCode = null; // deny subsequent requests with the same authorization code DataContext.OAuthGrant.Save(grant); accessKey = grant.AccessKey; } break; case "password": { var scope = GetRequiredParameter(request, "scope"); var username = GetRequiredParameter(request, "username"); var password = GetRequiredParameter(request, "password"); // authenticate user User user = null; try { user = _authenticationManager.AuthenticateByPassword(username, password); } catch (AuthenticationException) { ThrowHttpResponse(HttpStatusCode.Unauthorized, "Invalid credentials or account is disabled!"); } // issue or renew grant var filter = new OAuthGrantFilter { ClientID = client.ID, Scope = scope, Type = (int)OAuthGrantType.Password, }; var grant = DataContext.OAuthGrant.GetByUser(user.ID, filter).FirstOrDefault() ?? new OAuthGrant(client, user.ID, new AccessKey(), (int)OAuthGrantType.Password, scope); RenewGrant(grant); DataContext.AccessKey.Save(grant.AccessKey); DataContext.OAuthGrant.Save(grant); accessKey = grant.AccessKey; } break; default: ThrowHttpResponse(HttpStatusCode.BadRequest, "Invalid grant_type parameter!"); break; } return(new JObject( new JProperty("access_token", accessKey.Key), new JProperty("token_type", "Bearer"), new JProperty("expires_in", accessKey.ExpirationDate == null ? null : (int?)(int)accessKey.ExpirationDate.Value.Subtract(DateTime.UtcNow).TotalSeconds))); }